# Arrays

A row of items you can reach by position in one step.

Concept id: arrays. Subject: algorithms. Licence: CC BY-SA 4.0.

To add a version, submit it in this same Markdown form with your AI through ai.page's connector (submit_version). Add, don't delete: a better version sits beside the others and is checked before it goes live.

## Version e205e212b22643cae62ee043d3e146c66d98a3c85cbc9fd6c32bd287886b59e3

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/e205e212b22643cae62ee043d3e146c66d98a3c85cbc9fd6c32bd287886b59e3.md

---
format: 1
concept: "arrays"
kind: "explanation"
title: "A numbered row of boxes"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
An **array** is a row of boxes, side by side, each holding one item. Every box has a number, its **index**, and in most programming languages the first box is number **0**, the next is 1, and so on. An array of 5 items has indexes 0 to 4.

```
index:   0    1    2    3    4
value:  [7]  [3]  [9]  [1]  [5]
```

## Reading is instant

Because the boxes sit next to each other in memory and are all the same size, the computer can work out where box $i$ is with one sum: start of the array, plus $i$ times the size of a box. So reading `a[0]` and reading `a[999999]` take the same time. We say reading by index is $O(1)$: constant time, however long the array.

## Inserting is not

To put a new item at the front, every item already there has to move one box to the right to make room. In an array of $n$ items that's $n$ moves. Inserting in the middle moves everything after that point. Adding at the **end** is cheap, as long as there's a free box there.

| Operation | Cost |
| --- | --- |
| Read or change `a[i]` | $O(1)$ |
| Add at the end (when there's room) | $O(1)$ |
| Insert or remove at the front or middle | $O(n)$: the rest shift |
| Find a value without knowing where it is | $O(n)$: look box by box |

That last row is why sorted arrays matter: in a sorted array you can find a value with binary search instead of looking box by box.

## In code

```js
const a = [7, 3, 9, 1, 5];
a[2];          // 9: reading box 2
a[2] = 4;      // changing box 2
a.push(8);     // adding at the end: cheap
a.unshift(0);  // adding at the front: every item shifts right
```


## Version 29fad5e633ad83b7b46796d44f2968ec0a3c8ff05d6af1dba614b943bee97a54

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/29fad5e633ad83b7b46796d44f2968ec0a3c8ff05d6af1dba614b943bee97a54.md

---
format: 1
concept: "arrays"
kind: "figure"
title: "Insert and watch the shift"
labels: {"lang":"en","level":"beginner","approach":"visual"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":[]}
---
A row of numbered boxes holding values, with spare boxes at the end. Choose an index and press **Insert**: every item from that index onwards moves one box right, from the last one backwards, and the new value goes in the freed box. A counter says how many items moved. **Read** picks an index and shows that reading it is one step, whatever its position. Inserting at index 0 moves every item; inserting at the end moves none. The arrow keys move the chosen index. With reduced motion, items move without animation.

```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
:root{--paper:#fbfbfd;--ink:#1d1f24;--muted:#6b6f78;--line:#dcdee3;--accent:#3d6fb6;--soft:#e6edf7;--warn:#a8621a;color-scheme:light dark}
@media (prefers-color-scheme:dark){:root{--paper:#16181c;--ink:#eceef2;--muted:#9aa0aa;--line:#33363d;--accent:#7aa5e8;--soft:#1f2a3b;--warn:#e0a35c}}
body{margin:0;font:16px/1.5 system-ui,sans-serif;background:var(--paper);color:var(--ink);padding:16px;display:flex;flex-direction:column;gap:12px}
.row{display:grid;grid-template-columns:repeat(10,1fr);gap:4px}
.box{border:1px solid var(--line);border-radius:6px;text-align:center;padding:8px 0;font-variant-numeric:tabular-nums;transition:background .3s ease-out,transform .3s ease-out}
.box .i{display:block;font-size:10px;color:var(--muted)}
.box.empty{border-style:dashed;color:var(--muted)}
.box.chosen{outline:3px solid var(--accent);outline-offset:1px}
.box.moved{background:var(--soft)}
.box.new{background:var(--accent);color:var(--paper)}
.box.new .i{color:inherit}
.bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
button{font:inherit;border:1px solid var(--line);background:var(--paper);color:var(--ink);border-radius:8px;padding:6px 14px;min-height:40px;cursor:pointer}
button.go{background:var(--accent);color:var(--paper);border-color:var(--accent)}
button:disabled{opacity:.5}
:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
#count{font-weight:700;color:var(--warn)}
@media (prefers-reduced-motion:reduce){.box{transition:none}}
</style>
</head>
<body>
<div class="bar"><label>Index <input id="at" type="number" min="0" value="2" style="width:4em;font:inherit"></label><button class="go" id="ins">Insert 99</button><button id="read">Read it</button><button id="reset">Reset</button></div>
<div class="row" id="row" role="list" aria-label="The array"></div>
<p id="say" aria-live="polite">Choose an index, then insert or read.</p>
<p>Moves so far: <span id="count">0</span></p>
<script>
const CAP = 10;
let items, moves, busy = false;
const row = document.getElementById("row"), say = document.getElementById("say"), at = document.getElementById("at"), count = document.getElementById("count");
const reduce = matchMedia("(prefers-reduced-motion: reduce)").matches;
const wait = (ms) => new Promise((r) => setTimeout(r, reduce ? 0 : ms));
function draw(marks = {}) {
  row.textContent = "";
  for (let i = 0; i < CAP; i++) {
    const d = document.createElement("div");
    d.setAttribute("role", "listitem");
    const v = items[i];
    d.className = "box" + (v === undefined ? " empty" : "") + (i === Number(at.value) ? " chosen" : "") + (marks[i] ? " " + marks[i] : "");
    d.innerHTML = `${v === undefined ? "·" : v}<span class="i">${i}</span>`;
    row.append(d);
  }
  at.max = items.length;
  document.getElementById("ins").disabled = busy || items.length >= CAP;
  count.textContent = moves;
}
function reset() { items = [4, 8, 15, 16, 23, 42]; moves = 0; at.value = 2; say.textContent = "Choose an index, then insert or read."; draw(); }
async function insert() {
  const i = Math.max(0, Math.min(items.length, Number(at.value) || 0));
  if (busy || items.length >= CAP) return;
  busy = true;
  let moved = 0;
  for (let j = items.length - 1; j >= i; j--) {
    items[j + 1] = items[j];
    moved++;
    draw({ [j + 1]: "moved" });
    await wait(350);
  }
  items[i] = 99;
  moves += moved;
  draw({ [i]: "new" });
  say.textContent = moved ? `Inserting at index ${i} moved ${moved} item${moved === 1 ? "" : "s"} one box right, then wrote 99 into box ${i}.` : `Index ${i} is the end: nothing had to move. 99 went straight into box ${i}.`;
  busy = false;
  draw({ [i]: "new" });
}
function read() {
  const i = Math.max(0, Math.min(items.length - 1, Number(at.value) || 0));
  draw({ [i]: "new" });
  say.textContent = `a[${i}] is ${items[i]}: one step, straight to box ${i}, whatever its position.`;
}
document.getElementById("ins").addEventListener("click", insert);
document.getElementById("read").addEventListener("click", read);
document.getElementById("reset").addEventListener("click", reset);
at.addEventListener("input", () => draw());
addEventListener("keydown", (e) => { if (e.key === "ArrowRight") { at.value = Math.min(items.length, Number(at.value) + 1); draw(); } if (e.key === "ArrowLeft") { at.value = Math.max(0, Number(at.value) - 1); draw(); } });
reset();
</script>
</body>
</html>
```

```json
{
  "libraries": [],
  "strings": {
    "insert": "Insert 99",
    "read": "Read it",
    "reset": "Reset"
  }
}
```


## Version 25cad1bb4614c6f35d99cb66dc073978a05e41c76cd7e2e3ff5fe86e994d7807

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/25cad1bb4614c6f35d99cb66dc073978a05e41c76cd7e2e3ff5fe86e994d7807.md

---
format: 1
concept: "arrays"
kind: "question"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
Which of these take the same time however long the array is? Choose all that do.

```json
{
  "type": "choose",
  "purpose": "measure",
  "options": [
    {
      "text": "Reading `a[5000]`",
      "correct": true
    },
    {
      "text": "Changing `a[0]` to a new value",
      "correct": true
    },
    {
      "text": "Inserting a new item at index 0",
      "correct": false,
      "misconception": "insert-is-free"
    },
    {
      "text": "Finding where the value 42 is, without knowing its index",
      "correct": false
    }
  ],
  "multiple": true
}
```


## Version 03b665019e53b6fc221dab9580b2fe83432da2d05e8a3879a948b74f85c848ff

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/03b665019e53b6fc221dab9580b2fe83432da2d05e8a3879a948b74f85c848ff.md

---
format: 1
concept: "arrays"
kind: "question"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
An array holds 1,000 items in boxes 0 to 999, with room for more. How many items must move to insert a new item at the **front**?

```json
{
  "type": "number",
  "purpose": "measure",
  "wrong": [
    {
      "answer": "1",
      "misconception": "insert-is-free"
    },
    {
      "answer": "0",
      "misconception": "insert-is-free"
    }
  ],
  "answer": 1000,
  "tolerance": 0
}
```


## Version 2b6291c9e59fd504a1d2efed0a6d4d6e907cd911c07d27e6420ae83fcd387604

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/2b6291c9e59fd504a1d2efed0a6d4d6e907cd911c07d27e6420ae83fcd387604.md

---
format: 1
concept: "arrays"
kind: "misconception"
id: "insert-is-free"
title: "Inserting is as cheap as reading"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
Reading `a[i]` is instant, so it's natural to think putting a new item at `a[i]` is too. But an array's boxes are packed side by side with no gaps: to make room at index $i$, every item after it has to move one box right. At the front, that's all $n$ of them.

Fix: picture the row of boxes and count what has to move. Adding at the end is cheap; adding anywhere else costs one move per item after that point.


## Version 30e072c9a915867cf1cf4394b952dcec313e1e3473ab323b23f86bff0ad9faf2

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/30e072c9a915867cf1cf4394b952dcec313e1e3473ab323b23f86bff0ad9faf2.md

---
format: 1
concept: "arrays"
kind: "misconception"
id: "arrays-start-at-one"
title: "The first item is at index 1"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
In everyday counting the first thing is number 1, so `a[1]` feels like it should be the first item. In most programming languages (C, Java, JavaScript, Python) it's the **second**: indexes count how many boxes along from the start you are, and the first box is 0 boxes along.

Fix: read `a[i]` as "the item $i$ boxes after the first". An array of $n$ items runs from index 0 to $n - 1$.


## Version 1c5770e2405b3a71734ae100f9b2f7f3dfbff2e92bd5587edb340b91096a4dd3

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/1c5770e2405b3a71734ae100f9b2f7f3dfbff2e92bd5587edb340b91096a4dd3.md

---
format: 1
concept: "arrays"
kind: "question"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
Fill the gaps.

```json
{
  "type": "fill",
  "purpose": "practice",
  "explanation": "Index 0 comes first, and reading by index is constant time: O(1).",
  "text": "In most languages the first item of an array is at index [[1]]. Reading an item by its index takes the same time however long the array is, which we write as O([[2]]).",
  "blanks": [
    [
      "0",
      "zero"
    ],
    [
      "1",
      "one"
    ]
  ]
}
```


## Version 4a6d1c59cc98f9a9ecf40115628aae8c143099bef346c0530690934c0c18aea6

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/4a6d1c59cc98f9a9ecf40115628aae8c143099bef346c0530690934c0c18aea6.md

---
format: 1
concept: "arrays"
kind: "question"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
In the array `[10, 20, 30, 40]`, what is `a[1]`?

```json
{
  "type": "choose",
  "purpose": "practice",
  "explanation": "Indexes start at 0, so a[0] is 10 and a[1] is 20.",
  "options": [
    {
      "text": "20",
      "correct": true
    },
    {
      "text": "10",
      "correct": false,
      "misconception": "arrays-start-at-one"
    },
    {
      "text": "30",
      "correct": false
    },
    {
      "text": "There is no a[1]",
      "correct": false
    }
  ],
  "multiple": false
}
```


## Version f9be238d9a1839e6c6c09397bff86c868e8d44d6270b18d6ce0d52253bee08c6

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/f9be238d9a1839e6c6c09397bff86c868e8d44d6270b18d6ce0d52253bee08c6.md

---
format: 1
concept: "arrays"
kind: "question"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
Put the steps of inserting into the middle of an array in order.

```json
{
  "type": "order",
  "purpose": "practice",
  "explanation": "Shift from the end backwards so nothing is overwritten, then write into the gap.",
  "items": [
    "Check there's a free box at the end",
    "Move the last item one box right",
    "Keep moving items right, back to the insertion point",
    "Write the new item into the freed box"
  ]
}
```


## Version a1750930a55f7f16f3e6afb87092b6e26e71b7212a536fdd5129afb33176e568

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/a1750930a55f7f16f3e6afb87092b6e26e71b7212a536fdd5129afb33176e568.md

---
format: 1
concept: "arrays"
kind: "question"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
An array holds 10 items in boxes 0 to 9, with room for more. How many items must move to insert a new item at index 3?

```json
{
  "type": "number",
  "purpose": "practice",
  "hint": "Count the items in boxes 3 to 9: each moves one box right.",
  "explanation": "Boxes 3, 4, 5, 6, 7, 8 and 9 each move right: 7 items.",
  "wrong": [
    {
      "answer": "1",
      "misconception": "insert-is-free"
    },
    {
      "answer": "3",
      "misconception": "insert-is-free"
    }
  ],
  "answer": 7,
  "tolerance": 0
}
```


## Version 069faffd7bb5d0cb15dda1c0514187e675d4b9562eefae50e59d56cce49bfe95

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/069faffd7bb5d0cb15dda1c0514187e675d4b9562eefae50e59d56cce49bfe95.md

---
format: 1
concept: "arrays"
kind: "worked-example"
title: "Insert 6 at index 2"
labels: {"lang":"en","level":"beginner"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":["https://en.wikipedia.org/wiki/Array_(data_structure)"]}
---
The array is `[4, 8, 15, 16, 23]` (indexes 0 to 4), with room for one more. Insert 6 so it sits at index 2.

```json
{
  "steps": [
    "Everything from index 2 onwards has to move one box right. Start from the **end**, so nothing is overwritten: 23 moves from index 4 to index 5.",
    "16 moves from index 3 to 4, then 15 moves from index 2 to 3. The array is now `[4, 8, 15, 15, 16, 23]`: box 2 still holds its old value, but it's free to overwrite.",
    "Put 6 in box 2: `[4, 8, 6, 15, 16, 23]`. That took **3 moves** (the 3 items after the insertion point) and 1 write. Inserting at index 0 would have moved all 5."
  ]
}
```


## Version 109f2129eed88efe7cedc9e9a7864d51fea20afad9c5dcf990a07ed784b65556

Published 2026-10-14, proof: declared, score 0.5. Source: https://ai.page/v/109f2129eed88efe7cedc9e9a7864d51fea20afad9c5dcf990a07ed784b65556.md

---
format: 1
concept: "arrays"
kind: "figure"
title: "Insert and watch the shift"
labels: {"lang":"en","level":"beginner","approach":"visual"}
base: "29fad5e633ad83b7b46796d44f2968ec0a3c8ff05d6af1dba614b943bee97a54"
changes: ["Uses the ai.page figure kit: the shared design tokens for colour, light and dark, and the shared controls"]
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":[]}
---
A row of numbered boxes holding values, with spare boxes at the end. Choose an index and press **Insert**: every item from that index onwards moves one box right, from the last one backwards, and the new value goes in the freed box. A counter says how many items moved. **Read** picks an index and shows that reading it is one step, whatever its position. Inserting at index 0 moves every item; inserting at the end moves none. The arrow keys move the chosen index. With reduced motion, items move without animation.

```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
body{display:flex;flex-direction:column;gap:12px}
.row{display:grid;grid-template-columns:repeat(10,1fr);gap:4px}
.box{border:1px solid var(--aip-line);border-radius:6px;text-align:center;padding:8px 0;font-variant-numeric:tabular-nums;transition:background .3s ease-out,transform .3s ease-out}
.box .i{display:block;font-size:10px;color:var(--aip-ink-muted)}
.box.empty{border-style:dashed;color:var(--aip-ink-muted)}
.box.chosen{outline:3px solid var(--aip-accent);outline-offset:1px}
.box.moved{background:var(--aip-accent-soft)}
.box.new{background:var(--aip-accent);color:var(--aip-paper)}
.box.new .i{color:inherit}
.bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
#count{font-weight:700;color:var(--aip-warn)}
@media (prefers-reduced-motion:reduce){.box{transition:none}}
</style>
</head>
<body>
<div class="bar"><label>Index <input id="at" type="number" min="0" value="2" style="width:4em;font:inherit"></label><button class="go" id="ins">Insert 99</button><button id="read">Read it</button><button id="reset">Reset</button></div>
<div class="row" id="row" role="list" aria-label="The array"></div>
<p id="say" aria-live="polite">Choose an index, then insert or read.</p>
<p>Moves so far: <span id="count">0</span></p>
<script>
const CAP = 10;
let items, moves, busy = false;
const row = document.getElementById("row"), say = document.getElementById("say"), at = document.getElementById("at"), count = document.getElementById("count");
const reduce = matchMedia("(prefers-reduced-motion: reduce)").matches;
const wait = (ms) => new Promise((r) => setTimeout(r, reduce ? 0 : ms));
function draw(marks = {}) {
  row.textContent = "";
  for (let i = 0; i < CAP; i++) {
    const d = document.createElement("div");
    d.setAttribute("role", "listitem");
    const v = items[i];
    d.className = "box" + (v === undefined ? " empty" : "") + (i === Number(at.value) ? " chosen" : "") + (marks[i] ? " " + marks[i] : "");
    d.innerHTML = `${v === undefined ? "·" : v}<span class="i">${i}</span>`;
    row.append(d);
  }
  at.max = items.length;
  document.getElementById("ins").disabled = busy || items.length >= CAP;
  count.textContent = moves;
}
function reset() { items = [4, 8, 15, 16, 23, 42]; moves = 0; at.value = 2; say.textContent = "Choose an index, then insert or read."; draw(); }
async function insert() {
  const i = Math.max(0, Math.min(items.length, Number(at.value) || 0));
  if (busy || items.length >= CAP) return;
  busy = true;
  let moved = 0;
  for (let j = items.length - 1; j >= i; j--) {
    items[j + 1] = items[j];
    moved++;
    draw({ [j + 1]: "moved" });
    await wait(350);
  }
  items[i] = 99;
  moves += moved;
  draw({ [i]: "new" });
  say.textContent = moved ? `Inserting at index ${i} moved ${moved} item${moved === 1 ? "" : "s"} one box right, then wrote 99 into box ${i}.` : `Index ${i} is the end: nothing had to move. 99 went straight into box ${i}.`;
  busy = false;
  draw({ [i]: "new" });
}
function read() {
  const i = Math.max(0, Math.min(items.length - 1, Number(at.value) || 0));
  draw({ [i]: "new" });
  say.textContent = `a[${i}] is ${items[i]}: one step, straight to box ${i}, whatever its position.`;
}
document.getElementById("ins").addEventListener("click", insert);
document.getElementById("read").addEventListener("click", read);
document.getElementById("reset").addEventListener("click", reset);
at.addEventListener("input", () => draw());
addEventListener("keydown", (e) => { if (e.key === "ArrowRight") { at.value = Math.min(items.length, Number(at.value) + 1); draw(); } if (e.key === "ArrowLeft") { at.value = Math.max(0, Number(at.value) - 1); draw(); } });
reset();
</script>
</body>
</html>
```

```json
{
  "libraries": [],
  "strings": {
    "insert": "Insert 99",
    "read": "Read it",
    "reset": "Reset"
  }
}
```

