Skip to content

Tested prompt · Coding

Parse CSV with quoted fields: every AI model's reply, tested

We sent this hard coding prompt to all 16 models in llmwise, the same way the app sends a message, and checked every reply the same way. Here's each one as it came, with whether it passed, what it cost and how long it took.

Based on 16 of our test runs on , through OpenRouter with the app's own prompt and settings. Updated .

Short answer

14 of 16 models passed this coding prompt's check (tests); Claude Haiku 4.5 and DeepSeek V4 Pro didn't. The cheapest reply that passed was GLM 5.3 Flash's, at $0.00026; the fastest, GLM 5.3's in 2.6 s. The dearest reply, Claude Fable 5.1's, cost 267 times as much ($0.0697).

The prompt, as sent, and its check

Checked by tests, the same way for every model.

Parse CSV with quoted fields (hard)

Write a JavaScript function parseCsv(text) that parses CSV text into an array of rows, each an array of strings.
- Fields are separated by commas, and rows by \n or \r\n.
- A field may be wrapped in double quotes. Inside quotes, commas and line breaks are part of the field, and "" stands for one double quote.
- A quote inside a field that doesn't start with one is an ordinary character.
- A line break at the very end of the text doesn't start a new row, and an empty string gives [].
Reply with the whole function in one ```javascript code block: plain JavaScript for Node.js 22, no imports, no TypeScript.

The reply's parseCsv runs against these 8 tests; it passes when all of them do.

parseCsv("a,b,c\n1,2,3")  // → [["a", "b", "c"], ["1", "2", "3"]]
parseCsv('"x, y",z')  // → [["x, y", "z"]]
parseCsv('"say ""hi""",2')  // → [["say \"hi\"", "2"]]
parseCsv('"line1\nline2",end\r\nnext,row\r\n')  // → [["line1\nline2", "end"], ["next", "row"]]
parseCsv("a,,c\n,\n")  // → [["a", "", "c"], ["", ""]]
parseCsv("")  // → []
parseCsv('he said "no",x')  // → [["he said \"no\"", "x"]]
parseCsv('a,"b"\n"",c')  // → [["a", "b"], ["", "c"]]

Exactly what this prompt's replies are checked against, with every other prompt of our test runs.

Every model's result

All 16 models on this prompt, in catalog order.

Every model's reply to “Parse CSV with quoted fields”
ModelResultCostTimeReply
Claude Fable 5.1AnthropicPassed: All 8 tests passed.$0.069714.3 s1,229 tokens
Claude Opus 5.5AnthropicPassed: All 8 tests passed.$0.027311.9 s563 tokens
Claude Sonnet 5.5AnthropicPassed: All 8 tests passed.$0.01145.3 s978 tokens
Claude Sonnet 5AnthropicPassed: All 8 tests passed.$0.018715.8 s463 tokens
Claude Haiku 4.5AnthropicFailed: 5 of 8 tests passed. First failure: parseCsv('"line1\nline2",end\r\nnext,row\r\n'): Expected values to be strictly deep-equal:$0.00333.5 s559 tokens
GPT-6 AstraOpenAIPassed: All 8 tests passed.$0.03149.1 s313 tokens
GPT-6 SolOpenAIPassed: All 8 tests passed.$0.00818.9 s349 tokens
GPT-6 LunaOpenAIPassed: All 8 tests passed.$0.000437.2 s315 tokens
Gemini 3.1 Pro (preview)GooglePassed: All 8 tests passed.$0.029120.6 s462 tokens
Gemini 3.8 FlashGooglePassed: All 8 tests passed.$0.00225.0 s480 tokens
DeepSeek V4.1 FlashDeepSeekPassed: All 8 tests passed.$0.001311.6 s377 tokens
DeepSeek V4 ProDeepSeekFailed: No answer within Pro's reply limit of 8,000 tokens: the model spent them all reasoning.$0.032369.1 s195 tokens
Grok 4.7xAIPassed: All 8 tests passed.$0.0403100.4 s347 tokens
Kimi K3MoonshotPassed: All 8 tests passed.$0.00694.1 s360 tokens
GLM 5.3Z.aiPassed: All 8 tests passed.$0.00242.6 s456 tokens
GLM 5.3 FlashZ.aiPassed: All 8 tests passed.$0.000268.4 s426 tokens

Cost: what OpenRouter charged us for the reply. Time: from sending to the whole reply. Reply: its length in tokens, thinking not counted. In llmwise you pay per message, not per token: each of these replies counted as one message on Pro.

Every reply

The 2 replies that failed first, then the ones that passed, from the cheapest up.

  1. Claude Haiku 4.5

    Failed: 5 of 8 tests passed. First failure: parseCsv('"line1\nline2",end\r\nnext,row\r\n'): Expected values to be strictly deep-equal:

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
    
      const rows = [];
      let currentRow = [];
      let currentField = "";
      let inQuotes = false;
      let i = 0;
    
      while (i < text.length) {
        const char = text[i];
    
        if (inQuotes) {
          if (char === '"') {
            if (i + 1 < text.length && text[i + 1] === '"') {
              // "" inside quotes means a literal quote
              currentField += '"';
              i += 2;
            } else {
              // End of quoted field
              inQuotes = false;
              i++;
            }
          } else {
            // Any character (including comma, newline) inside quotes is part of the field
            currentField += char;
            i++;
          }
        } else {
          if (char === '"') {
            // Start of quoted field
            inQuotes = true;
            i++;
          } else if (char === ",") {
            // Field separator
            currentRow.push(currentField);
            currentField = "";
            i++;
          } else if (char === "\r") {
            // Handle \r\n or \r
            currentRow.push(currentField);
            currentField = "";
            if (i + 1 < text.length && text[i + 1] === "\n") {
              i += 2;
            } else {
              i++;
            }
            // Only add row if there's more content after the line break
            if (i < text.length) {
              rows.push(currentRow);
              currentRow = [];
            }
          } else if (char === "\n") {
            // Row separator
            currentRow.push(currentField);
            currentField = "";
            i++;
            // Only add row if there's more content after the line break
            if (i < text.length) {
              rows.push(currentRow);
              currentRow = [];
            }
          } else {
            // Ordinary character
            currentField += char;
            i++;
          }
        }
      }
    
      // Add the last field and row
      currentRow.push(currentField);
      rows.push(currentRow);
    
      return rows;
    }
    ```

    518 tokens in, 559 out · 3.5 s · $0.0033 · 1 message on Pro · answered by anthropic/claude-haiku-4.5 via Amazon Bedrock ·

  2. DeepSeek V4 Pro

    Failed: No answer within Pro's reply limit of 8,000 tokens: the model spent them all reasoning.

    (no reply)

    493 tokens in, 8,000 out (7,805 of them reasoning) · 69.1 s · $0.0323 · 1 message on Pro · answered by deepseek/deepseek-v4-pro-0813 via CoreWeave ·

  3. GLM 5.3 Flash

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let i = 0;
      // Track whether the field started with a quote
      let fieldQuoted = false;
    
      function endField() {
        row.push(field);
        field = "";
        fieldQuoted = false;
      }
    
      function endRow() {
        endField();
        rows.push(row);
        row = [];
      }
    
      while (i < text.length) {
        const ch = text[i];
    
        if (inQuotes) {
          if (ch === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i += 2;
            } else {
              inQuotes = false;
              i++;
            }
          } else {
            field += ch;
            i++;
          }
          continue;
        }
    
        if (field === "" && !fieldQuoted && ch === '"') {
          fieldQuoted = true;
          inQuotes = true;
          i++;
          continue;
        }
    
        if (ch === ",") {
          endField();
          i++;
          continue;
        }
    
        if (ch === "\r" || ch === "\n") {
          // handle \r\n as one line break
          if (ch === "\r" && text[i + 1] === "\n") i++;
          // a line break at the very end of the text doesn't start a new row
          if (i + 1 >= text.length || (ch === "\r" && i + 2 >= text.length)) {
            i++;
            continue;
          }
          endRow();
          i++;
          continue;
        }
    
        field += ch;
        i++;
      }
    
      // final field/row if anything pending (a field was started)
      if (field !== "" || fieldQuoted || row.length > 0) {
        endRow();
      }
    
      return rows;
    }
    ```

    495 tokens in, 434 out (8 of them reasoning) · 8.4 s · $0.0003 · 1 message on Pro · answered by z-ai/glm-5.3-flash via AtlasCloud ·

  4. GPT-6 Luna

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
    
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let endedWithRowBreak = false;
    
      for (let i = 0; i < text.length; i++) {
        const char = text[i];
    
        if (inQuotes) {
          if (char === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              inQuotes = false;
            }
          } else {
            field += char;
          }
          endedWithRowBreak = false;
          continue;
        }
    
        if (char === '"' && field === "") {
          inQuotes = true;
          endedWithRowBreak = false;
        } else if (char === ",") {
          row.push(field);
          field = "";
          endedWithRowBreak = false;
        } else if (char === "\n" || (char === "\r" && text[i + 1] === "\n")) {
          row.push(field);
          rows.push(row);
          row = [];
          field = "";
          if (char === "\r") i++;
          endedWithRowBreak = true;
        } else {
          field += char;
          endedWithRowBreak = false;
        }
      }
    
      if (!endedWithRowBreak) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    481 tokens in, 762 out (447 of them reasoning) · 7.2 s · $0.0004 · 1 message on Pro · answered by openai/gpt-6-luna via OpenAI ·

  5. DeepSeek V4.1 Flash

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === '') return [];
    
      const rows = [];
      let row = [];
      let field = '';
      let inQuotes = false;
      let atFieldStart = true;
      let i = 0;
      const n = text.length;
    
      const endField = () => {
        row.push(field);
        field = '';
        atFieldStart = true;
      };
    
      const endRow = () => {
        endField();
        rows.push(row);
        row = [];
      };
    
      while (i < n) {
        const ch = text[i];
    
        if (inQuotes) {
          if (ch === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i += 2;
            } else {
              inQuotes = false;
              i += 1;
            }
          } else {
            field += ch;
            i += 1;
          }
          continue;
        }
    
        if (ch === '"' && atFieldStart) {
          inQuotes = true;
          atFieldStart = false;
          i += 1;
          continue;
        }
    
        if (ch === ',') {
          endField();
          i += 1;
          continue;
        }
    
        if (ch === '\r' && text[i + 1] === '\n') {
          endRow();
          i += 2;
          continue;
        }
    
        if (ch === '\n') {
          endRow();
          i += 1;
          continue;
        }
    
        field += ch;
        atFieldStart = false;
        i += 1;
      }
    
      if (row.length > 0 || field !== '') {
        endRow();
      }
    
      return rows;
    }
    ```

    522 tokens in, 1,914 out (1,537 of them reasoning) · 11.6 s · $0.0013 · 1 message on Pro · answered by deepseek/deepseek-v4.1-flash via StreamLake ·

  6. Gemini 3.8 Flash

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === '') return [];
    
      // Remove a single trailing newline if present
      if (text.endsWith('\r\n')) {
        text = text.slice(0, -2);
      } else if (text.endsWith('\n')) {
        text = text.slice(0, -1);
      }
    
      if (text === '') return [];
    
      const rows = [];
      let currentRow = [];
      let currentField = '';
      let inQuotes = false;
      let isStartOfField = true;
    
      for (let i = 0; i < text.length; i++) {
        const char = text[i];
    
        if (inQuotes) {
          if (char === '"') {
            if (text[i + 1] === '"') {
              currentField += '"';
              i++; // skip escaped quote
            } else {
              inQuotes = false;
            }
          } else {
            currentField += char;
          }
        } else {
          if (isStartOfField && char === '"') {
            inQuotes = true;
            isStartOfField = false;
          } else if (char === ',') {
            currentRow.push(currentField);
            currentField = '';
            isStartOfField = true;
          } else if (char === '\r' && text[i + 1] === '\n') {
            currentRow.push(currentField);
            rows.push(currentRow);
            currentRow = [];
            currentField = '';
            isStartOfField = true;
            i++; // skip '\n'
          } else if (char === '\n') {
            currentRow.push(currentField);
            rows.push(currentRow);
            currentRow = [];
            currentField = '';
            isStartOfField = true;
          } else {
            currentField += char;
            isStartOfField = false;
          }
        }
      }
    
      currentRow.push(currentField);
      rows.push(currentRow);
    
      return rows;
    }
    ```

    515 tokens in, 480 out · 5.0 s · $0.0022 · 1 message on Pro · answered by google/gemini-3.8-flash via Google ·

  7. GLM 5.3

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === '') return [];
      const rows = [];
      let row = [];
      let field = '';
      let inQuotes = false;
      let i = 0;
      const n = text.length;
    
      while (i < n) {
        const c = text[i];
    
        if (inQuotes) {
          if (c === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i += 2;
            } else {
              inQuotes = false;
              i++;
            }
          } else {
            field += c;
            i++;
          }
          continue;
        }
    
        if (c === '"' && field === '' && (i === 0 || /[\n\r,]/.test(text[i - 1]))) {
          inQuotes = true;
          i++;
        } else if (c === ',') {
          row.push(field);
          field = '';
          i++;
        } else if (c === '\r' && text[i + 1] === '\n') {
          row.push(field);
          rows.push(row);
          row = [];
          field = '';
          i += 2;
        } else if (c === '\n' || c === '\r') {
          row.push(field);
          rows.push(row);
          row = [];
          field = '';
          i++;
        } else {
          field += c;
          i++;
        }
      }
    
      // Only emit a final row if there's a pending field/row (avoids trailing newline creating empty row)
      if (field !== '' || row.length > 0) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```
    
    Notes on behavior:
    - A quote only starts a quoted field at the beginning of a field (start of input, after a comma, or after a line break), per your third rule; otherwise `"` is literal.
    - `""` inside quotes becomes a single `"`.
    - Embedded `\n`/`\r\n` inside quotes stays in the field; a trailing newline at the end of input doesn't create an empty final row; `''` returns `[]`.

    518 tokens in, 463 out (7 of them reasoning) · 2.6 s · $0.0024 · 1 message on Pro · answered by z-ai/glm-5.3 via Wafer ·

  8. Kimi K3

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
    
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let quoted = false; // current field started with a quote
      let afterQuote = false; // just closed a quoted field
    
      for (let i = 0; i < text.length; i++) {
        const c = text[i];
    
        if (inQuotes) {
          if (c === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              inQuotes = false;
              afterQuote = true;
            }
          } else {
            field += c;
          }
        } else if (c === '"' && field === "" && !afterQuote) {
          inQuotes = true;
          quoted = true;
        } else if (c === ",") {
          row.push(field);
          field = "";
          quoted = false;
          afterQuote = false;
        } else if (c === "\n" || c === "\r") {
          if (c === "\r" && text[i + 1] === "\n") i++;
          row.push(field);
          rows.push(row);
          row = [];
          field = "";
          quoted = false;
          afterQuote = false;
        } else {
          field += c;
        }
      }
    
      // Trailing line break doesn't start a new row; otherwise flush last field/row.
      if (field !== "" || quoted || row.length > 0) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    568 tokens in, 367 out (7 of them reasoning) · 4.1 s · $0.0069 · 1 message on Pro · answered by moonshotai/kimi-k3 via Together ·

  9. GPT-6 Sol

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
    
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let atFieldStart = true;
      let endedWithRowBreak = false;
    
      for (let i = 0; i < text.length; i++) {
        const char = text[i];
    
        if (inQuotes) {
          if (char === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              inQuotes = false;
            }
          } else {
            field += char;
          }
          endedWithRowBreak = false;
        } else if (char === '"' && atFieldStart) {
          inQuotes = true;
          atFieldStart = false;
          endedWithRowBreak = false;
        } else if (char === ",") {
          row.push(field);
          field = "";
          atFieldStart = true;
          endedWithRowBreak = false;
        } else if (char === "\n" || (char === "\r" && text[i + 1] === "\n")) {
          row.push(field);
          rows.push(row);
          row = [];
          field = "";
          atFieldStart = true;
          endedWithRowBreak = true;
          if (char === "\r") i++;
        } else {
          field += char;
          atFieldStart = false;
          endedWithRowBreak = false;
        }
      }
    
      if (!endedWithRowBreak) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    481 tokens in, 712 out (363 of them reasoning) · 8.9 s · $0.0081 · 1 message on Pro · answered by openai/gpt-6-sol via OpenAI ·

  10. Claude Sonnet 5.5

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let fieldStarted = false; // any content or quote seen in current row
      const n = text.length;
    
      for (let i = 0; i < n; i++) {
        const c = text[i];
    
        if (inQuotes) {
          if (c === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              inQuotes = false;
            }
          } else {
            field += c;
          }
          continue;
        }
    
        if (c === '"' && field === "" && !fieldStarted) {
          inQuotes = true;
          fieldStarted = true;
        } else if (c === ",") {
          row.push(field);
          field = "";
          fieldStarted = false;
          rowHasContent = true;
        } else if (c === "\n" || (c === "\r" && text[i + 1] === "\n")) {
          if (c === "\r") i++;
          row.push(field);
          rows.push(row);
          row = [];
          field = "";
          fieldStarted = false;
          rowHasContent = false;
        } else {
          field += c;
          fieldStarted = true;
        }
      }
    
      // Final row: only if the text didn't end with a line break
      if (field !== "" || fieldStarted || row.length > 0 || inQuotes) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```
    
    Wait — `rowHasContent` is undeclared, which would throw in strict mode. Here is the corrected version:
    
    ```javascript
    function parseCsv(text) {
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let fieldStarted = false;
      const n = text.length;
    
      for (let i = 0; i < n; i++) {
        const c = text[i];
    
        if (inQuotes) {
          if (c === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              inQuotes = false;
            }
          } else {
            field += c;
          }
          continue;
        }
    
        if (c === '"' && !fieldStarted) {
          inQuotes = true;
          fieldStarted = true;
        } else if (c === ",") {
          row.push(field);
          field = "";
          fieldStarted = false;
        } else if (c === "\n" || (c === "\r" && text[i + 1] === "\n")) {
          if (c === "\r") i++;
          row.push(field);
          rows.push(row);
          row = [];
          field = "";
          fieldStarted = false;
        } else {
          field += c;
          fieldStarted = true;
        }
      }
    
      if (fieldStarted || field !== "" || row.length > 0 || inQuotes) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    671 tokens in, 978 out · 5.3 s · $0.0114 · 1 message on Pro · answered by anthropic/claude-sonnet-5.5 via Anthropic ·

  11. Claude Sonnet 5

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      const rows = [];
      let row = [];
      let field = '';
      let i = 0;
      const n = text.length;
      let inQuotes = false;
    
      while (i < n) {
        const c = text[i];
    
        if (inQuotes) {
          if (c === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i += 2;
            } else {
              inQuotes = false;
              i++;
            }
          } else {
            field += c;
            i++;
          }
          continue;
        }
    
        if (c === '"' && field === '') {
          inQuotes = true;
          i++;
        } else if (c === ',') {
          row.push(field);
          field = '';
          i++;
        } else if (c === '\r' && text[i + 1] === '\n') {
          row.push(field);
          rows.push(row);
          row = [];
          field = '';
          i += 2;
        } else if (c === '\n') {
          row.push(field);
          rows.push(row);
          row = [];
          field = '';
          i++;
        } else {
          field += c;
          i++;
        }
      }
    
      // Only push the final row if there's actually pending content;
      // a trailing line break should not create an extra empty row.
      if (field !== '' || row.length > 0) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    667 tokens in, 1,737 out (1,274 of them reasoning) · 15.8 s · $0.0187 · 1 message on Pro · answered by anthropic/claude-sonnet-5 via Claude Platform on AWS ·

  12. Claude Opus 5.5

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      const rows = [];
      const n = text.length;
      if (n === 0) return rows;
    
      let row = [];
      let field = '';
      let inQuotes = false;
      let atFieldStart = true; // no characters consumed yet for the current field
      let rowPending = false;  // current row has consumed at least one character
      let i = 0;
    
      while (i < n) {
        const c = text[i];
    
        if (inQuotes) {
          if (c === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i += 2;
            } else {
              inQuotes = false;
              i += 1;
            }
          } else {
            field += c;
            i += 1;
          }
          continue;
        }
    
        if (c === '"' && atFieldStart) {
          inQuotes = true;
          atFieldStart = false;
          rowPending = true;
          i += 1;
          continue;
        }
    
        if (c === ',') {
          row.push(field);
          field = '';
          atFieldStart = true;
          rowPending = true;
          i += 1;
          continue;
        }
    
        if (c === '\n' || (c === '\r' && text[i + 1] === '\n')) {
          row.push(field);
          rows.push(row);
          row = [];
          field = '';
          atFieldStart = true;
          rowPending = false;
          i += c === '\r' ? 2 : 1;
          continue;
        }
    
        field += c;
        atFieldStart = false;
        rowPending = true;
        i += 1;
      }
    
      if (rowPending || inQuotes) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    669 tokens in, 1,200 out (637 of them reasoning) · 11.9 s · $0.0273 · 1 message on Pro · answered by anthropic/claude-opus-5.5 via Claude Platform on AWS ·

  13. Gemini 3.1 Pro

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
      
      const rows = [];
      let currentRow = [];
      let currentField = "";
      let inQuotes = false;
      
      for (let i = 0; i < text.length; i++) {
        const c = text[i];
        
        if (inQuotes) {
          if (c === '"') {
            if (i + 1 < text.length && text[i + 1] === '"') {
              currentField += '"';
              i++; // Skip escaped quote
            } else {
              inQuotes = false;
            }
          } else {
            currentField += c;
          }
        } else {
          if (c === '"' && currentField === "") {
            inQuotes = true;
          } else if (c === ',') {
            currentRow.push(currentField);
            currentField = "";
          } else if (c === '\r' && i + 1 < text.length && text[i + 1] === '\n') {
            currentRow.push(currentField);
            rows.push(currentRow);
            currentRow = [];
            currentField = "";
            i++; // Skip \n
          } else if (c === '\n') {
            currentRow.push(currentField);
            rows.push(currentRow);
            currentRow = [];
            currentField = "";
          } else {
            currentField += c;
          }
        }
      }
      
      // If the text didn't end with a newline, push the final field and row.
      // We also push if the very last character was a comma (meaning an empty field at the end).
      if (currentField !== "" || currentRow.length > 0 || (text.length > 0 && text[text.length - 1] === ',')) {
        currentRow.push(currentField);
        rows.push(currentRow);
      }
      
      return rows;
    }
    ```

    515 tokens in, 2,339 out (1,877 of them reasoning) · 20.6 s · $0.0291 · 1 message on Pro · answered by google/gemini-3.1-pro-preview via Google ·

  14. GPT-6 Astra

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
    
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let atFieldStart = true;
    
      for (let i = 0; i < text.length; i++) {
        const char = text[i];
    
        if (inQuotes) {
          if (char === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              inQuotes = false;
            }
          } else {
            field += char;
          }
          continue;
        }
    
        if (char === '"' && atFieldStart) {
          inQuotes = true;
          atFieldStart = false;
        } else if (char === ",") {
          row.push(field);
          field = "";
          atFieldStart = true;
        } else if (
          char === "\n" ||
          (char === "\r" && text[i + 1] === "\n")
        ) {
          if (char === "\r") i++;
          row.push(field);
          rows.push(row);
          row = [];
          field = "";
          atFieldStart = true;
        } else {
          field += char;
          atFieldStart = false;
        }
      }
    
      if (row.length > 0 || !atFieldStart) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    481 tokens in, 532 out (219 of them reasoning) · 9.1 s · $0.0314 · 1 message on Pro · answered by openai/gpt-6-astra via OpenAI ·

  15. Grok 4.7

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      if (text === "") return [];
    
      const rows = [];
      let row = [];
      let field = "";
      let inQuotes = false;
      let i = 0;
    
      while (i < text.length) {
        const c = text[i];
    
        if (inQuotes) {
          if (c === '"') {
            if (text[i + 1] === '"') {
              field += '"';
              i += 2;
            } else {
              inQuotes = false;
              i += 1;
            }
          } else {
            field += c;
            i += 1;
          }
          continue;
        }
    
        if (c === '"') {
          if (field.length === 0) inQuotes = true;
          else field += '"';
          i += 1;
          continue;
        }
    
        if (c === ",") {
          row.push(field);
          field = "";
          i += 1;
          continue;
        }
    
        if (c === "\n" || (c === "\r" && text[i + 1] === "\n")) {
          i += c === "\r" ? 2 : 1;
          row.push(field);
          rows.push(row);
          row = [];
          field = "";
          continue;
        }
    
        field += c;
        i += 1;
      }
    
      if (text[text.length - 1] !== "\n" || inQuotes) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```

    1,717 tokens in, 8,172 out (7,825 of them reasoning) · 100.4 s · $0.0403 · 1 message on Pro · answered by x-ai/grok-4.7 via xAI ·

  16. Claude Fable 5.1

    Passed: All 8 tests passed.

    ```javascript
    function parseCsv(text) {
      const rows = [];
      if (text.length === 0) return rows;
    
      let row = [];
      let field = '';
      let i = 0;
      const n = text.length;
    
      while (i < n) {
        const ch = text[i];
    
        if (field === '' && ch === '"' && fieldStart) {
          // Quoted field
          i++;
          while (i < n) {
            const c = text[i];
            if (c === '"') {
              if (text[i + 1] === '"') {
                field += '"';
                i += 2;
              } else {
                i++;
                break;
              }
            } else {
              field += c;
              i++;
            }
          }
          // After closing quote, consume any trailing chars until delimiter/newline
          while (i < n && text[i] !== ',' && text[i] !== '\n' && text[i] !== '\r') {
            field += text[i];
            i++;
          }
          fieldStart = false;
          continue;
        }
    
        if (ch === ',') {
          row.push(field);
          field = '';
          fieldStart = true;
          i++;
        } else if (ch === '\n' || (ch === '\r' && text[i + 1] === '\n')) {
          row.push(field);
          rows.push(row);
          row = [];
          field = '';
          fieldStart = true;
          i += ch === '\r' ? 2 : 1;
        } else {
          field += ch;
          fieldStart = false;
          i++;
        }
      }
    
      // Handle final field/row unless text ended exactly on a line break
      const endsWithNewline = text.endsWith('\n');
      if (!endsWithNewline) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    
      // fieldStart tracks whether we're at the beginning of a field (so a quote
      // there opens a quoted field, while a quote mid-field is a literal char).
      var fieldStart;
    }
    ```
    
    Note: `fieldStart` is declared with `var` (hoisted) and starts `undefined`, which is falsy — so the first field wouldn't be treated as quoted. Here is the corrected version with it initialized properly:
    
    ```javascript
    function parseCsv(text) {
      const rows = [];
      if (text.length === 0) return rows;
    
      let row = [];
      let field = '';
      let fieldStart = true;
      let i = 0;
      const n = text.length;
    
      while (i < n) {
        const ch = text[i];
    
        if (fieldStart && ch === '"') {
          i++;
          while (i < n) {
            const c = text[i];
            if (c === '"') {
              if (text[i + 1] === '"') {
                field += '"';
                i += 2;
              } else {
                i++;
                break;
              }
            } else {
              field += c;
              i++;
            }
          }
          while (i < n && text[i] !== ',' && text[i] !== '\n' && text[i] !== '\r') {
            field += text[i];
            i++;
          }
          fieldStart = false;
          continue;
        }
    
        if (ch === ',') {
          row.push(field);
          field = '';
          fieldStart = true;
          i++;
        } else if (ch === '\n' || (ch === '\r' && text[i + 1] === '\n')) {
          row.push(field);
          rows.push(row);
          row = [];
          field = '';
          fieldStart = true;
          i += ch === '\r' ? 2 : 1;
        } else {
          field += ch;
          fieldStart = false;
          i++;
        }
      }
    
      if (!text.endsWith('\n')) {
        row.push(field);
        rows.push(row);
      }
    
      return rows;
    }
    ```
    
    Use the second block.

    669 tokens in, 1,229 out · 14.3 s · $0.0697 · 1 message on Pro · answered by anthropic/claude-fable-5.1 via Anthropic ·

More coding prompts

The other coding prompts, each with every model's reply, and the results across all five.

Questions

Which AI does best on “Parse CSV with quoted fields”?

14 of 16 models passed this coding prompt's check (tests); Claude Haiku 4.5 and DeepSeek V4 Pro didn't. The cheapest reply that passed was GLM 5.3 Flash's, at $0.00026; the fastest, GLM 5.3's in 2.6 s. The dearest reply, Claude Fable 5.1's, cost 267 times as much ($0.0697).

What does a reply to “Parse CSV with quoted fields” cost?

Through the models' APIs, what OpenRouter charged us ran from $0.00026 (GLM 5.3 Flash) to $0.0697 (Claude Fable 5.1) for this prompt. In llmwise you don't pay by the token: a reply like these counts as one message on Pro, whichever model answers.

Claude, GPT, Gemini, DeepSeek, Grok, Kimi, and GLM, in one chat.

See what a message costs before you send it. Free is 5 messages to try; sign in with an email link, no password or card.