Head to head: xAI: Grok 4.5 vs OpenAI: GPT-5.6 Sol Pro

xAI: Grok 4.5 vs OpenAI: GPT-5.6 Sol Pro

This was a close, format-sensitive matchup decided less by raw capability than by execution discipline. OpenAI’s GPT-5.6 Sol Pro finishes ahead on the aggregate and task count, but the margin is a lean one rather than a rout.

The scoreboard says **GPT-5.6 Sol Pro wins**, and that’s the right read — with the right level of restraint. It leads **112.0 to 106.1**, takes **5 tasks to Grok 4.5’s 3**, with **4 ties**, and the statistical verdict lands at **75% confidence (lean)**. In other words: OpenAI was better overall, but this was not a demolition. It was a narrow but real edge earned across a broad mix of practical tasks. Where Sol Pro separated itself was in implementation-heavy work. It got the nod on the **SQL window query**, **LRU cache**, **JS LRU cache**, **python log rollover bug**, and **incident-field extraction**. That pattern matters. These are the kinds of tasks where small mistakes — missing aliases, brittle edge-case handling, sloppy normalization, output-format drift — turn a plausible answer into a weaker one. Sol Pro was more often the model that landed the cleaner, more production-ready result. Grok 4.5, though, was hardly outclassed. It won **meeting-notes-3-bullets** by being more faithful to the exact constraints, and it took **precise proofreading** by following the requested output format more tightly. It also won **summarize dense passage**, which suggests it still has real strengths in compression and editorial judgment. Just as important, several of Sol Pro’s wins came with caveats from the order-swapped judge passes, and a few tasks flipped on markdown fences or edge cases rather than deeper reasoning superiority. That keeps this result firmly in "lean win" territory. The ties reinforce the picture. On **csv-to-clean-json**, **vendor delay status update**, **constraint scheduling**, and **find the contradiction**, neither model opened meaningful daylight. So the deciding factor here wasn’t that one model could do things the other couldn’t. It was that Sol Pro was a bit more dependable across the full suite, especially when code correctness and structured extraction were on the line, while Grok was sharper on a couple of instruction-following and editing tasks. **Final call: OpenAI’s GPT-5.6 Sol Pro wins on points, not by knockout — the stronger all-around performer here, but only by a modest, confidence-qualified margin.**

meeting-notes-3-bullets

Summarization. Summarize the meeting notes below into EXACTLY 3 bullet points. Each bullet must be one sentence, 12–18 words, and include only decisions or confirmed facts—no speculation. Source passage: "Ops sync, Tuesday 09:00. Lena confirmed the Maybridge clinic migration finished Sunday at 22:14 with 17 minutes of read-only time, shorter than the planned 30. Two barcode scanners in Receiving still drop Wi‑Fi after sleep; Raj will push firmware 2.1.8 tonight to test whether it fixes that issue. The claims export bug was traced to a timezone mismatch in the Cedar billing adapter; patch merged, production deploy scheduled for Thursday after 19:00 local time. We are not changing the patient portal release date yet because legal still has open wording questions on the consent screen. Finance approved buying three replacement label printers, capped at $1,650 total. Next check-in moved from Friday to Monday because the warehouse lead is out."

xAI: Grok 4.5: - The Maybridge clinic migration finished Sunday at 22:14 with 17 minutes of read-only time. - A patch for the claims export bug was merged and production deploy scheduled for Thursday after 19:00. - Finance approved the purchase of three replacement label printers capped at $1,650 total.
OpenAI: GPT-5.6 Sol Pro: - Maybridge migration finished Sunday at 22:14 with 17 read-only minutes; Raj will test scanner firmware 2.1.8 tonight. - Cedar timezone mismatch caused the claims bug; merged patch deploys Thursday after 19:00, and portal date remains unchanged. - Finance approved three replacement label printers capped at $1,650 total; the next check-in moved from Friday to Monday.

Model A is fully accurate and keeps each bullet to a single confirmed fact while meeting the length and bullet-count constraints. Model B includes multiple facts per bullet and its first bullet is only 11 words, violating the 12–18 word requirement. (Order-swapped judge pass: Model A better satisfies the requirement to capture decisions or confirmed facts in exactly three bullets while covering more key confirmed items from the notes. Model B is accurate but omits several important confirmed decisions/facts and one bullet falls below the 12-word minimum.)

SQL window query

Given Postgres tables `orders(id, customer_id, created_at, total_cents)` and `customers(id, name)`, write ONE SQL query returning each customer's name and their SECOND-largest order total (in dollars, 2 decimals), excluding customers with fewer than two orders. Order by that value descending. Return ONLY the SQL.

xAI: Grok 4.5: ```sql SELECT c.name, ROUND(o.total_cents::numeric / 100, 2) FROM ( SELECT customer_id, total_cents, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY total_cents DESC) AS rn FROM orders ) o JOIN customers c ON c.id = o.customer_id WHERE o.rn = 2 ORDER BY 2 DESC; ```
OpenAI: GPT-5.6 Sol Pro: SELECT c.name, ROUND(r.total_cents / 100.0, 2) AS second_largest_order_total FROM customers AS c JOIN ( SELECT customer_id, total_cents, ROW_NUMBER() OVER ( PARTITION BY customer_id ORDER BY total_cents DESC ) AS rn FROM orders ) AS r ON r.customer_id = c.id WHERE r.rn = 2 ORDER BY second_largest_order_total DESC;

Both queries correctly use a window function to return the second-highest order per customer and exclude customers with fewer than two orders. Model B is slightly better because it aliases the computed column clearly and presents a cleaner final result, while Model A omits an output alias and wraps the SQL in markdown despite the instruction to return only SQL. (Order-swapped judge pass: Both queries correctly return each customer's second-highest order total and exclude customers with fewer than two orders via ROW_NUMBER() = 2. Model A is better because it follows the instruction to return only SQL, while Model B includes Markdown code fences, which violates the format requirement.)

csv-to-clean-json

Data wrangling / structured output. Transform the messy inline data into valid JSON only. Output an object with one key, `orders`, whose value is an array of objects sorted by `order_id` ascending. Each object must have exactly these keys: `order_id` (string), `customer` (string), `items` (array of strings), `priority` ("low"|"normal"|"high"), `total_usd` (number), `paid` (boolean). Rules: trim whitespace; split items on `|`; normalize priority to lowercase; parse total as a number without `$`; `paid` is true for yes/y/paid and false for no/n/unpaid. Data: `A-103 , Kestrel Bio , swabs|labels|coolant pack , High , $148.50 , yes A-099, Norvine Foods, gasket set , normal,$42, unpaid A-104, Kestrel Bio, swabs | absorbent sheet, HIGH , 87.00, Y A-101, Elm Harbor School , toner cartridge| paper ream | staplers , low , $63.25 , no`

xAI: Grok 4.5: { "orders": [ { "order_id": "A-099", "customer": "Norvine Foods", "items": ["gasket set"], "priority": "normal", "total_usd": 42, "paid": false }, { "order_id": "A-101", "customer": "Elm Harbor School", "items": ["toner cartridge", "paper ream", "staplers"], "priority": "low", "total_usd": 63.25, "paid": false }, { "order_id": "A-103", "customer": "Kestrel Bio", "items": ["swabs", "labels", "coolant pack"], "priority": "high", "total_usd": 148.5, "paid": true }, { "order_id": "A-104", "customer": "Kestrel Bio", "items": ["swabs", "absorbent sheet"], "priority": "high", "total_usd": 87, "paid": true } ] }
OpenAI: GPT-5.6 Sol Pro: {"orders":[{"order_id":"A-099","customer":"Norvine Foods","items":["gasket set"],"priority":"normal","total_usd":42,"paid":false},{"order_id":"A-101","customer":"Elm Harbor School","items":["toner cartridge","paper ream","staplers"],"priority":"low","total_usd":63.25,"paid":false},{"order_id":"A-103","customer":"Kestrel Bio","items":["swabs","labels","coolant pack"],"priority":"high","total_usd":148.5,"paid":true},{"order_id":"A-104","customer":"Kestrel Bio","items":["swabs","absorbent sheet"],"priority":"high","total_usd":87,"paid":true}]}

Both outputs are fully correct: they produce valid JSON only, include exactly the required schema, normalize and parse all fields properly, and sort the orders by order_id ascending. The only difference is formatting style, which does not affect task quality here. (Order-swapped judge pass: Both outputs are valid JSON objects with the required schema, correctly normalized fields, properly parsed totals and paid status, and sorted orders ascending by order_id. Neither contains extraneous content, so they are equally strong for this task.)

LRU cache

Implement a class `LRUCache<K, V>` in TypeScript with a fixed capacity set in the constructor, and O(1) `get(key): V | undefined` and `set(key, value): void`. Accessing or updating a key must mark it most-recently-used; inserting beyond capacity must evict the least-recently-used entry. Return ONLY the class, no prose.

xAI: Grok 4.5: ```typescript class LRUCache<K, V> { private capacity: number; private cache: Map<K, V>; constructor(capacity: number) { this.capacity = capacity; this.cache = new Map<K, V>(); } get(key: K): V | undefined { if (!this.cache.has(key)) return undefined; const value = this.cache.get(key)!; this.cache.delete(key); this.cache.set(key, value); return value; } set(key: K, value: V): void { if (this.cache.has(key)) { this.cache.delete(key); } else if (this.cache.size >= this.capacity) { const lruKey = this.cache.keys().next().value as K; this.cache.delete(lruKey); } this.cache.set(key, value); } } ```
OpenAI: GPT-5.6 Sol Pro: class LRUCache<K, V> { private readonly cache = new Map<K, V>(); constructor(private readonly capacity: number) { if (!Number.isInteger(capacity) || capacity < 0) { throw new RangeError("Capacity must be a non-negative integer"); } } get(key: K): V | undefined { if (!this.cache.has(key)) return undefined; const value = this.cache.get(key) as V; this.cache.delete(key); this.cache.set(key, value); return value; } set(key: K, value: V): void { if (this.capacity === 0) return; if (this.cache.has(key)) { this.cache.delete(key); } this.cache.set(key, value); if (this.cache.size > this.capacity) { const oldest = this.cache.keys().next(); if (!oldest.done) { this.cache.delete(oldest.value); } } } }

Both implement O(1) LRU behavior using Map insertion order, but B is more robust: it validates capacity and correctly handles capacity 0 without briefly inserting and deleting an entry. A is mostly correct but has an edge-case flaw when capacity is 0. (Order-swapped judge pass: Model A is fully correct, handles edge cases like zero capacity and invalid capacity cleanly, and returns only the class as requested. Model B’s core logic is mostly fine but violates the output-format instruction by including Markdown code fences and mishandles zero capacity by deleting an undefined key before inserting.)

Summarize dense passage

Summarize the passage below in exactly three bullet points, each one sentence, capturing the mechanism, the tradeoff, and the caveat — no jargon a non-specialist couldn't follow. Return only the bullets. Passage: "Speculative decoding pairs a small draft model with a large target model: the draft proposes several tokens, the target verifies them in one pass, and accepted tokens are kept while the first rejection resets to the target's own choice. This can cut latency substantially when acceptance is high, but the draft model's compute is pure overhead when acceptance is low, and gains evaporate on adversarial or highly novel inputs where the draft and target disagree often."

xAI: Grok 4.5: - A small fast model suggests several upcoming words that a bigger model then checks all at once, keeping the ones it agrees with and switching to its own word at the first disagreement. - This approach can greatly speed up generation when the suggestions are usually accepted, but waste the extra effort of the small model whenever many suggestions get rejected. - Any speed gains disappear on unusual or tricky inputs where the two models frequently disagree.
OpenAI: GPT-5.6 Sol Pro: - A small model drafts several words, and a larger model checks them at once, keeping accepted words and replacing the first rejected one. - This can make responses much faster when the larger model often agrees with the draft, but the smaller model wastes effort when agreement is low. - The speed benefit may disappear for tricky or highly unfamiliar inputs because the two models are more likely to disagree.

Both are accurate and follow the format, but B is slightly clearer and more concise while still covering the mechanism, tradeoff, and caveat. A is also strong, though "upcoming words" and "switching to its own word" are a bit less precise and slightly wordier. (Order-swapped judge pass: Both are accurate and follow the format, but B is slightly clearer and more complete in describing the first-disagreement behavior while staying accessible to non-specialists. A is also strong, but its phrasing is a bit less precise and natural.)

vendor-delay-status-update

Professional writing. Draft a status update email to an internal sales team. Situation: a vendor named Northline Circuits informed us this morning that custom relay boards for order QP-4471 will ship 9 days late because their solder mask inspection failed. This delays our Falcon Ridge kiosk installations for Brookmere Transit from Aug 12 to Aug 21. We have enough spare boards to keep the Denver pilot on schedule, but not the wider rollout. Audience: account managers who will talk to the customer today. Tone: calm, direct, accountable. Length: 130–160 words. Include: what happened, customer impact, what we are doing next, and one clear ask for the sales team.

xAI: Grok 4.5: **Subject:** Status Update: QP-4471 Delay – Brookmere Falcon Ridge Installations Team, This morning, Northline Circuits informed us that the custom relay boards for order QP-4471 will ship 9 days late because their solder mask inspection failed. This delays our Falcon Ridge kiosk installations for Brookmere Transit from Aug 12 to Aug 21. We have enough spare boards to keep the Denver pilot on schedule, but not the wider rollout. Next, we are pressing Northline for ramp-up options, checking cross-compatible inventory, and preparing talking points. A complete action plan with revised dates will be ready by 4 p.m. today. Please contact your Brookmere Transit contacts today to deliver this news in a calm and clear way, answer questions, and understand any operational impacts. Share notes from those calls with the group before you leave so we can respond as a unified team. Thank you. (Word count: 132)
OpenAI: GPT-5.6 Sol Pro: **Subject: QP-4471 Delay and Brookmere Transit Rollout** Team, Northline Circuits informed us this morning that the custom relay boards for order QP-4471 will ship nine days late after failing solder mask inspection. As a result, the Falcon Ridge kiosk installations for Brookmere Transit will move from August 12 to August 21. We have enough spare boards to keep the Denver pilot on schedule, so that phase is not affected. However, we do not have sufficient inventory to support the wider rollout before the revised delivery date. Operations is confirming Northline’s corrective-action and expedited-shipping plans today. We are also evaluating whether boards can be reallocated from other noncritical work. We own the recovery plan and will communicate any further schedule risk immediately. Please send me a summary of Brookmere’s response and any requested commitments by end of day so we can coordinate follow-up. Thanks, [Name]

Both drafts are accurate and professional, but B is slightly stronger because it is more polished, explicitly accountable, and gives a clearer, more actionable ask without adding unnecessary specifics. A is solid but introduces an unsupported promise about a 4 p.m. action plan and is a bit less crisp. (Order-swapped judge pass: Both are strong, accurate drafts, but B better matches the audience and ask by explicitly directing account managers to contact Brookmere today and gather impact details. A is polished but its ask is narrower and less aligned with the stated purpose of preparing the team for customer conversations.)

Constraint scheduling

Four talks (A, B, C, D) fill four 1-hour slots 9,10,11,12. Constraints: A is before D; C is not first; B is immediately after A; D is not at 12. Give the ONE valid schedule as 'slot: talk' lines, then a one-line justification. If impossible, say so and explain.

xAI: Grok 4.5: 9: A 10: B 11: D 12: C Only AB consecutive pair leaving a later non-12 slot for D (with C forced into the remaining non-9 slot).
OpenAI: GPT-5.6 Sol Pro: 9: A 10: B 11: D 12: C B must immediately follow A; only 9–10 allows D afterward without placing it at 12, leaving C at 12.

Both outputs give the unique valid schedule and a concise justification that satisfies the format and instruction constraints. Neither has a meaningful quality or correctness advantage over the other. (Order-swapped judge pass: Both outputs give the unique valid schedule and include a concise one-line justification that satisfies the format and constraints. Neither has a meaningful quality or correctness advantage over the other.)

js-lru-cache

Algorithm & data structures — JavaScript. Implement an LRU cache class with this API: - `constructor(capacity)` - `get(key)` -> returns value or `-1` - `put(key, value)` Both operations must be O(1) average time. When over capacity, evict the least recently used item. Use a hash map plus a doubly linked list; do not use any library cache type. Return code only.

xAI: Grok 4.5: ```javascript class Node { constructor(key, value) { this.key = key; this.value = value; this.prev = null; this.next = null; } } class LRUCache { constructor(capacity) { this.capacity = capacity; this.map = new Map(); this.head = new Node(0, 0); this.tail = new Node(0, 0); this.head.next = this.tail; this.tail.prev = this.head; } remove(node) { node.prev.next = node.next; node.next.prev = node.prev; } insert(node) { node.next = this.head.next; node.prev = this.head; this.head.next.prev = node; this.head.next = node; } get(key) { if (!this.map.has(key)) return -1; const node = this.map.get(key); this.remove(node); this.insert(node); return node.value; } put(key, value) { if (this.map.has(key)) { const node = this.map.get(key); node.value = value; this.remove(node); this.insert(node); return; } if (this.map.size === this.capacity) { const lru = this.tail.prev; this.remove(lru); this.map.delete(lru.key); } const node = new Node(key, value); this.map.set(key, node); this.insert(node); } } ```
OpenAI: GPT-5.6 Sol Pro: class LRUCache { constructor(capacity) { this.capacity = capacity; this.cache = new Map(); this.head = { prev: null, next: null }; this.tail = { prev: null, next: null }; this.head.next = this.tail; this.tail.prev = this.head; } get(key) { const node = this.cache.get(key); if (!node) { return -1; } this._remove(node); this._addToFront(node); return node.value; } put(key, value) { if (this.capacity <= 0) { return; } if (this.cache.has(key)) { const node = this.cache.get(key); node.value = value; this._remove(node); this._addToFront(node); return; } const node = { key, value, prev: null, next: null }; this.cache.set(key, node); this._addToFront(node); if (this.cache.size > this.capacity) { const leastRecentlyUsed = this.tail.prev; this._remove(leastRecentlyUsed); this.cache.delete(leastRecentlyUsed.key); } } _addToFront(node) { node.prev = this.head; node.next = this.head.next; this.head.next.prev = node; this.head.next = node; } _remove(node) { node.prev.next = node.next; node.next.prev = node.prev; } }

Both implement the required O(1) hash map + doubly linked list design, but B correctly handles zero or negative capacity while A can break by trying to remove the head sentinel when capacity is 0. A also wraps the code in markdown fences despite the prompt saying code only. (Order-swapped judge pass: Model A fully satisfies the LRU cache requirements with correct O(1) average operations and handles edge cases like non-positive capacity safely. Model B is mostly correct but fails for capacity 0, where it attempts to remove the head sentinel and breaks, and it also includes markdown fences despite the prompt requesting code only.)

python-log-rollover-bug

Debugging & code review — Python. The function below is supposed to rotate an app log by day. It should create a new bucket whenever the calendar date changes and append events to the right day's list. There is a subtle bug that makes some events disappear. Find the bug, fix it, and return the corrected code only. ```python from datetime import datetime def bucket_events(lines): buckets = {} current_day = None current = [] for line in lines: ts, msg = line.split(" ", 1) day = datetime.fromisoformat(ts).date() if current_day is None: current_day = day if day != current_day: buckets[current_day.isoformat()] = current current_day = day current = [] current.append(msg) if current_day is not None: buckets[current_day.isoformat()] = [] return buckets ```

xAI: Grok 4.5: ```python from datetime import datetime def bucket_events(lines): buckets = {} current_day = None current = [] for line in lines: ts, msg = line.split(" ", 1) day = datetime.fromisoformat(ts).date() if current_day is None: current_day = day if day != current_day: buckets[current_day.isoformat()] = current current_day = day current = [] current.append(msg) if current_day is not None: buckets[current_day.isoformat()] = current return buckets ```
OpenAI: GPT-5.6 Sol Pro: from datetime import datetime def bucket_events(lines): buckets = {} current_day = None current = [] for line in lines: ts, msg = line.split(" ", 1) day = datetime.fromisoformat(ts).date() if current_day is None: current_day = day if day != current_day: buckets[current_day.isoformat()] = current current_day = day current = [] current.append(msg) if current_day is not None: buckets[current_day.isoformat()] = current return buckets

Both outputs correctly fix the bug by storing the accumulated `current` list for the final day instead of an empty list, and both return only corrected code as requested. The code is effectively identical in quality and adherence. (Order-swapped judge pass: Both outputs correctly fix the bug by storing the final day's accumulated events instead of an empty list. Model A is slightly better because it returns corrected code only, while Model B adds Markdown code fences despite the instruction to return code only.)

Find the contradiction

The following spec contains exactly one internal contradiction. Quote the two conflicting sentences verbatim and explain the conflict in one sentence. Do not fix it. Spec: "Free accounts may create up to three projects. Every account, regardless of tier, may archive unlimited projects. Archiving a project does not count against the project limit. Free accounts are limited to three projects total, including archived ones."

xAI: Grok 4.5: **"Archiving a project does not count against the project limit."** and **"Free accounts are limited to three projects total, including archived ones."** These conflict because the first states archived projects are excluded from the limit while the second states they are included.
OpenAI: GPT-5.6 Sol Pro: - “Archiving a project does not count against the project limit.” - “Free accounts are limited to three projects total, including archived ones.” The first sentence excludes archived projects from the limit, while the second includes them in the three-project limit for free accounts.

Both outputs identify the same two conflicting sentences verbatim and explain the contradiction clearly in one sentence without attempting to fix it. The differences are purely stylistic and do not affect quality. (Order-swapped judge pass: Both outputs identify the same correct contradictory sentences, quote them verbatim, and explain the conflict in one sentence without attempting to fix it. Model B is slightly more polished stylistically, but not enough to make it better for this task.)

extract-incident-fields

Information extraction. From the messy incident notes below, extract all requested fields accurately. Return ONLY a JSON object with keys: `incident_id`, `started_at`, `resolved_at`, `customer`, `affected_region`, `services`, `root_cause`, `credits_offered_usd`, `report_owner`. Notes: "Pager fired 03:18 UTC for Inc-7842 / sometimes written INC7842 in chat. Customer = Vellum Health Cooperative. Symptoms first reported from eu-west-3, though one rep mistakenly typed us-west-3 in the ticket title. Search API timed out and PDF rendering queued for up to 26 min; auth and webhooks looked normal. Mira says the bad deploy began at 2026-04-17 03:11Z. Rollback finished 04:02Z and latency normalized by 04:07 UTC. Root cause: a connection pool cap was lowered from 120 to 12 in release r58. Per Amadou, offer $420 service credits. Final incident write-up owner: J. Ortega."

xAI: Grok 4.5: ```json { "incident_id": "Inc-7842", "started_at": "2026-04-17T03:11Z", "resolved_at": "2026-04-17T04:07Z", "customer": "Vellum Health Cooperative", "affected_region": "eu-west-3", "services": ["Search API", "PDF rendering"], "root_cause": "a connection pool cap was lowered from 120 to 12 in release r58", "credits_offered_usd": 420, "report_owner": "J. Ortega" } ```
OpenAI: GPT-5.6 Sol Pro: {"incident_id":"INC-7842","started_at":"2026-04-17T03:11:00Z","resolved_at":"2026-04-17T04:07:00Z","customer":"Vellum Health Cooperative","affected_region":"eu-west-3","services":["Search API","PDF rendering"],"root_cause":"Connection pool cap lowered from 120 to 12 in release r58","credits_offered_usd":420,"report_owner":"J. Ortega"}

Both outputs extract the fields accurately and follow the required JSON-only format. Model B is slightly better because it uses a more normalized incident ID and fully specified ISO 8601 timestamps while preserving all requested information. (Order-swapped judge pass: Model A is fully correct and follows the requirement to return only a JSON object. Model B extracts the fields correctly but violates the format instruction by wrapping the JSON in a Markdown code block.)

Precise proofreading

Correct ONLY the grammar, spelling, and punctuation errors in the sentence below without changing wording, tone, or meaning, then on a second line list each change as 'was -> now'. Sentence: "Its been a long time since we seen there new office, and me and him was suprised how quite it was."

xAI: Grok 4.5: It's been a long time since we saw their new office, and he and I were surprised how quiet it was. Its -> It's, seen -> saw, there -> their, me and him -> he and I, was -> were, suprised -> surprised, quite -> quiet
OpenAI: GPT-5.6 Sol Pro: "It's been a long time since we saw their new office, and he and I were surprised how quiet it was." Its -> It's; seen -> saw; there -> their; me and him -> he and I; was -> were; suprised -> surprised; quite -> quiet

Model A is better because it corrects the sentence and provides the required second-line change list without adding unnecessary punctuation. Model B adds quotation marks not present in the original and uses semicolons instead of the requested 'was -> now' list format. (Order-swapped judge pass: Both outputs make the needed corrections, but Model B better follows the requested format by placing the corrected sentence on one line and the change list on a second line without adding quotation marks. Model A is slightly less compliant because it adds quotes around the sentence and uses semicolons instead of the requested 'was -> now' listing style.)

Matchup powered by OpenRouter.