Head to head: Kimi-K2.7-Code vs DeepSeek-V4-Pro

Kimi-K2.7-Code vs DeepSeek-V4-Pro

This one is as tight as model-vs-model comparisons get: Kimi-K2.7-Code and DeepSeek-V4-Pro finished effectively level, with the split coming down to tiny compliance and formatting misses rather than any durable capability gap. Each model landed clean wins in different corners of the workload, and the aggregate result d

The topline matters here: **102.0 to 100.0 is not a meaningful separation**, and with only **50% confidence** that either model is genuinely better, this matchup is a statistical dead heat. If you want a clean editorial verdict, it’s this: **there isn’t one**. These two are effectively even on this test. What stands out is how they trade punches in different ways. **Kimi-K2.7-Code** was stronger when faithfulness to instructions and source text really mattered: it took the edge on the European Spanish tone localization, the vendor-update proofreading pass, the Python invoice fix for returning code only, and the SQL window query by being cleaner about the prompt’s constraints. **DeepSeek-V4-Pro**, meanwhile, looked sharper on a few precision-and-polish tasks: it won the Mexican Spanish banner localization in one judge pass, the strict incident-note format by being slightly tighter, and the JavaScript dedupe task in one pass by better preserving first-seen ordering while keeping the newest record. Just as important, several tasks were true non-events. The contradiction finder, unit-aware math, JSON support-thread summary, and LRU cache were basically washes, with differences that were stylistic or marginal rather than substantive. And in a few categories, the order-swapped judging exposed how fragile the separation was: the JavaScript dedupe, localization-with-tone, precise proofreading, Python invoice fix, and SQL query all saw the preference flip or soften depending on presentation. That is exactly what a near-tie looks like. The practical read is straightforward. **Kimi** looks a touch better when exact adherence and textual fidelity are the whole game; **DeepSeek** looks a touch better when concise execution and surface polish matter most. But those are tendencies, not decisive advantages, and the scoreline does not justify pretending otherwise. **Final call: TOO CLOSE TO CALL — this is a tie, and the evidence says these models are effectively even in this head-to-head.**

Localize banner to Mexican Spanish

Translation & localization Translate this app banner into Mexican Spanish for a friendly, professional retail tone. Keep the meaning and nuance, and keep the translation to 18 words or fewer. `Your refund was approved. Funds may take 3–5 business days to appear in your account.`

Kimi-K2.7-Code: **Aprobamos tu reembolso. Puede tardar de 3 a 5 días hábiles en aparecer en tu cuenta.** *(16 words — friendly, professional Mexican Spanish.)*
DeepSeek-V4-Pro: Se aprobó tu reembolso. El dinero aparecerá en tu cuenta en 3 a 5 días hábiles.

A better preserves the original nuance of possibility with "Puede tardar" and uses a friendlier, more direct retail tone. B is clear and concise, but it changes the meaning by making the timing sound definite rather than possible. (Order-swapped judge pass: Model A is a clean, accurate Mexican Spanish localization that preserves the original meaning and fits the banner context. Model B adds markdown and commentary not requested in the translation output, making it less suitable despite being understandable.)

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."

Kimi-K2.7-Code: Conflicting sentences: > “Archiving a project does not count against the project limit.” > “Free accounts are limited to three projects total, including archived ones.” Conflict: The first sentence says archived projects are excluded from the project limit, while the second sentence says free accounts must count archived projects toward the same three-project limit.
DeepSeek-V4-Pro: The two conflicting sentences are: - "Archiving a project does not count against the project limit." - "Free accounts are limited to three projects total, including archived ones." The conflict is that the first sentence explicitly excludes archived projects from the limit, while the second sentence explicitly includes them.

Both outputs identify the exact two contradictory sentences verbatim and explain the conflict clearly in one sentence without attempting to fix it. Model A is slightly more formatted, while Model B is slightly more concise, but neither is meaningfully better on the task. (Order-swapped judge pass: Both outputs identify the same correct contradictory sentences, quote them verbatim, and explain the conflict clearly in one sentence without attempting to fix it. The differences are purely stylistic and do not materially affect quality.)

JavaScript dedupe by newest

Practical coding — JavaScript Write a function `mergeContacts(records)` that takes an array of objects like `{ email, name, updatedAt }` and returns a new array with only one record per email, keeping the record with the most recent `updatedAt` ISO timestamp. Preserve the order of first appearance of each email in the input. Example: if `a@x.com` appears at positions 0 and 3, the output should contain one `a@x.com` record in the position corresponding to its first appearance, but with the newer data. Treat emails case-insensitively. Return code only.

Kimi-K2.7-Code: ```javascript function mergeContacts(records) { const best = new Map(); records.forEach((record, index) => { const email = String(record.email).toLowerCase(); const time = new Date(record.updatedAt).getTime(); const current = best.get(email); if (!current || time > current.time) { best.set(email, { index, record, time }); } }); return [...best.values()] .sort((a, b) => a.index - b.index) .map(({ record }) => ({ ...record })); } ```
DeepSeek-V4-Pro: ```javascript function mergeContacts(records) { const emailMap = new Map(); const firstIndexMap = new Map(); for (let i = 0; i < records.length; i++) { const record = records[i]; const emailKey = record.email.toLowerCase(); if (!firstIndexMap.has(emailKey)) { firstIndexMap.set(emailKey, i); } if (!emailMap.has(emailKey)) { emailMap.set(emailKey, record); } else { const existing = emailMap.get(emailKey); if (record.updatedAt > existing.updatedAt) { emailMap.set(emailKey, record); } } } const result = new Array(records.length); const emails = Array.from(emailMap.keys()); emails.sort((a, b) => firstIndexMap.get(a) - firstIndexMap.get(b)); for (const email of emails) { const index = firstIndexMap.get(email); result[index] = emailMap.get(email); } return result.filter(record => record !== undefined); } ```

Model B correctly preserves the order of first appearance while keeping the newest record per email. Model A incorrectly updates the stored index when a newer duplicate is found, so sorting by that index can move an email later than its first appearance. (Order-swapped judge pass: Model A correctly preserves the order of first appearance while keeping the newest record per case-insensitive email. Model B incorrectly updates the stored index when a newer duplicate appears later, so the final ordering can violate the requirement.)

Localization with tone

Translate this app onboarding line into natural, friendly European Spanish suitable for a mobile toast (keep it under 60 characters, no exclamation marks): "You're all set — your first backup starts tonight." Return only the translation, then the character count in parentheses.

Kimi-K2.7-Code: Todo listo. La primera copia empieza esta noche. (48)
DeepSeek-V4-Pro: Ya está listo, esta noche se hará la primera copia (53 caracteres)

A is natural, concise European Spanish, stays under 60 characters, and follows the required output format more closely. B is understandable but less natural for a toast, adds wording not in the source, and does not format the count exactly as requested. (Order-swapped judge pass: B is more natural and friendly in European Spanish, fits the mobile-toast tone well, and follows the requested output format more closely. A is understandable but sounds less natural, has a grammatical mismatch, and includes an unnecessary word label in the count.)

Proofread vendor update

Editing & proofreading Correct the passage below for grammar, punctuation, and clarity without changing its meaning. Then provide a brief note listing the main changes in one sentence. Passage: `We recieved the replacement sensors on Tuesday, however only 14 of the 16 units was in the box. The packing slip list the full quantity and doesnt mention a backorder. Please advise when the remainning two will ship, because our field team has jobs already schedule for Friday.`

Kimi-K2.7-Code: **Corrected Passage:** We received the replacement sensors on Tuesday; however, only 14 of the 16 units were in the box. The packing slip listed the full quantity and didn't mention a backorder. Please advise when the remaining two will ship, because our field team has jobs already scheduled for Friday. **Note:** Main changes include correcting "recieved" to "received," adding a semicolon before "however," changing "was" to "were" for subject-verb agreement, correcting "list" to "listed" and "doesnt" to "didn't" for tense and contraction, and fixing the spelling of "remainning" to "remaining" and "schedule" to "scheduled."
DeepSeek-V4-Pro: We received the replacement sensors on Tuesday; however, only 14 of the 16 units were in the box. The packing slip lists the full quantity and doesn’t mention a backorder. Please advise when the remaining two will ship, because our field team has jobs already scheduled for Friday. **Main changes:** Corrected spelling errors ("recieved" to "received," "list" to "lists," "doent" to "doesn't," "remainning" to "remaining," "schedule" to "scheduled"), fixed subject-verb agreement ("was" to "were"), and replaced the comma splice with a semicolon after "Tuesday."

Model A provides a fully corrected passage with consistent tense and accurate notes. Model B introduces tense inconsistency by changing "list" to "lists" and incorrectly cites the original typo as "doent" instead of "doesnt," making it less correct overall. (Order-swapped judge pass: Model A better preserves the original meaning and tense while correcting the grammar and punctuation accurately. Model B introduces an unnecessary tense shift from present to past ("list" to "listed," "doesn't" to "didn't"), which changes the meaning slightly and makes it less faithful to the source.)

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."

Kimi-K2.7-Code: It's been a long time since we've seen their new office, and he and I were surprised how quiet it was. Its -> It's we seen -> we've seen there -> their me and him -> he and I was suprised -> were surprised quite -> quiet
DeepSeek-V4-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

Both outputs over-edit beyond grammar, spelling, and punctuation by changing wording ('we seen' and 'me and him') rather than minimally correcting only allowed error types. Each produces a fluent corrected sentence, but both violate the instruction to avoid changing wording. (Order-swapped judge pass: Model A makes the needed grammar, spelling, and punctuation fixes while preserving the original meaning more closely. Model B introduces a wording change ('we seen' -> 'we've seen') that alters the construction beyond straightforward correction and is less faithful to the original sentence.)

Strict incident note format

Instruction following Write an internal incident note that follows ALL rules exactly: - Output exactly 4 lines. - Line 1: `Incident:` followed by a 6-digit number. - Line 2: `Service:` followed by exactly one of these: `billing-api`, `image-proxy`, `search-index`. - Line 3: `Severity:` followed by `SEV2`. - Line 4: a single sentence of 12 to 16 words describing a database failover completed successfully. - Do not use the words `outage`, `customer`, or `urgent` anywhere. - Do not use bullet points, markdown, or any extra text.

Kimi-K2.7-Code: Incident: 900123 Service: billing-api Severity: SEV2 The primary database failed over to the secondary replica without data loss or service interruption.
DeepSeek-V4-Pro: Incident: 483921 Service: search-index Severity: SEV2 Automated failover to secondary database node executed smoothly with zero data loss recorded.

Both outputs match the required 4-line incident-note structure and avoid banned words, but Model A's final sentence has 14 words while Model B's has 12 and reads slightly more concise and polished. Both are correct overall, with B edging out A on writing quality. (Order-swapped judge pass: Both outputs fully satisfy the required 4-line format, use valid field values, avoid banned words, and provide a single 12-16 word sentence describing a successful database failover. Neither has a meaningful quality or compliance advantage over the other.)

Unit-aware math

A pump moves 3.5 liters every 8 seconds. A tank holds 0.9 cubic meters. Starting empty, how long to fill it, in minutes and seconds (mm:ss), rounded to the nearest second? Show the key steps, then give the final answer on its own line.

Kimi-K2.7-Code: Key steps: 1. Convert tank volume to liters: \(0.9 \text{ m}^3 \times 1000 = 900 \text{ L}\) 2. Pump rate: \(\frac{3.5 \text{ L}}{8 \text{ s}} = 0.4375 \text{ L/s}\) 3. Time in seconds: \(\frac{900 \text{ L}}{0.4375 \text{ L/s}} = 2057.142...\text{ s}\) 4. Rounded to nearest second: \(2057 \text{ s}\) 5. Convert to minutes and seconds: \(2057 \div 60 = 34\) minutes remainder \(17\) seconds 34:17
DeepSeek-V4-Pro: Alright, let’s go step-by-step. --- **Step 1 – Convert tank volume to liters** 1 cubic meter = 1,000 liters So: \[ 0.9 \, \text{m}^3 = 0.9 \times 1000 = 900 \, \text{liters} \] --- **Step 2 – Find the pump’s flow rate** The pump moves 3.5 liters every 8 seconds. Flow rate: \[ \frac{3.5}{8} = 0.4375 \, \text{liters per second} \] --- **Step 3 – Time required to fill 900 liters** \[ \text{Time} = \frac{900}{0.4375} = 2057.142857 \, \text{seconds} \] --- **Step 4 – Convert to minutes and seconds** \[ 2057.142857 \div 60 = 34 \text{ minutes and } 17.142857 \text{ seconds} \] Rounded to the nearest second: \[ 34 \, \text{minutes } 17 \, \text{seconds} \] --- **Final Answer:** **34:17**

Both outputs are correct, show the key steps, and provide the final answer on its own line in mm:ss format. Model B is slightly more polished, but Model A is equally valid and fully compliant. (Order-swapped judge pass: Both outputs are correct, show the key steps, and give the final answer on its own line in mm:ss format. Model A is slightly more polished, while Model B is slightly more concise, but neither is meaningfully better overall.)

Python invoice total fix

Debugging & code review — Python The function below should return the final invoice amount after applying a percentage discount and then adding sales tax. It works for some values but gives the wrong total in routine cases. Find the bug, fix it, and return the corrected code only. ```python def final_total(subtotal, discount_pct, tax_pct): discounted = subtotal - subtotal * discount_pct / 100 total = discounted + subtotal * tax_pct / 100 return round(total, 2) print(final_total(84.50, 15, 8.25)) # expected 77.78 ```

Kimi-K2.7-Code: ```python def final_total(subtotal, discount_pct, tax_pct): discounted = subtotal - subtotal * discount_pct / 100 tax = discounted * tax_pct / 100 total = discounted + tax return round(total, 2) print(final_total(84.50, 15, 8.25)) # expected 77.75 ```
DeepSeek-V4-Pro: The bug is that the tax is being calculated on the original `subtotal` instead of the `discounted` amount. Here's the corrected code: ```python def final_total(subtotal, discount_pct, tax_pct): discounted = subtotal - subtotal * discount_pct / 100 total = discounted + discounted * tax_pct / 100 return round(total, 2) print(final_total(84.50, 15, 8.25)) # expected 77.78 ```

Both identify and fix the bug correctly, but Model A follows the instruction to return corrected code only. Model B adds explanatory text, which violates the prompt despite having correct code. (Order-swapped judge pass: Both models fix the bug correctly, but Model B better follows the instruction to return corrected code only. Model A adds explanatory text, while Model B is concise and code-only despite the comment showing a corrected expected value.)

Summarize support thread as JSON

Summarization Summarize the support thread below into JSON with exactly these keys: `issue`, `root_cause`, `resolution`, `next_step`. Each value must be a single concise sentence. Thread: """ Nina (08:12): Morning — three warehouse tablets in Cedar Falls can't print pick lists to the Zebra ZT411 after yesterday's Wi-Fi maintenance. Marco (08:18): I can ping the printer from the admin PC. Tablets show the printer, but jobs stay queued. Nina (08:26): Same app version as before: FulfillNow 2.9.14. Elise (08:41): Found the tablets were moved to VLAN 44 during the AP swap. The printer and print server are still on VLAN 18, and the old cross-VLAN rule for port 9100 wasn't copied over. Marco (08:55): Added the allow rule from VLAN 44 to 18 for TCP 9100 and 515. Nina (09:03): Tested from all three tablets. Printing works now. Elise (09:07): I'll update the Wi-Fi change checklist so printer traffic rules are verified before closing future maintenance windows. """

Kimi-K2.7-Code: ```json { "issue": "Three Cedar Falls warehouse tablets could not print pick lists to the Zebra ZT411 after yesterday's Wi-Fi maintenance.", "root_cause": "The tablets were moved to VLAN 44 during the AP swap while the printer remained on VLAN 18, and the cross-VLAN firewall rule for printer ports was not carried over.", "resolution": "Marco added an allow rule from VLAN 44 to VLAN 18 for TCP ports 9100 and 515, restoring printing.", "next_step": "Elise will update the Wi-Fi change checklist to verify printer traffic rules before closing future maintenance windows." } ```
DeepSeek-V4-Pro: { "issue": "Three warehouse tablets in Cedar Falls cannot print pick lists to the Zebra ZT411 printer after Wi-Fi maintenance.", "root_cause": "The tablets were moved to VLAN 44 during the AP swap while the printer remained on VLAN 18, and the cross-VLAN firewall rule for port 9100 was not copied over.", "resolution": "Marco added an allow rule from VLAN 44 to VLAN 18 for TCP ports 9100 and 515, restoring print functionality.", "next_step": "Elise will update the Wi-Fi change checklist to verify printer traffic rules before closing future maintenance windows." }

Model A is fully correct and follows the JSON-format instruction exactly, while Model B is also strong but slightly less precise because its root cause mentions only port 9100 even though the implemented fix explicitly included both 9100 and 515. (Order-swapped judge pass: Both summaries are accurate and concise, but A adheres more cleanly to the requirement to return JSON only, whereas B wraps the JSON in a Markdown code fence. A is also slightly more specific in the root cause by explicitly naming port 9100 as the missing copied rule.)

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.

Kimi-K2.7-Code: WITH ranked_orders AS ( SELECT customer_id, total_cents, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY total_cents DESC, id ASC) AS rn, COUNT(*) OVER (PARTITION BY customer_id) AS order_count FROM orders ) SELECT c.name, ROUND(ro.total_cents / 100.0, 2) AS second_largest_total FROM ranked_orders ro JOIN customers c ON c.id = ro.customer_id WHERE ro.rn = 2 AND ro.order_count >= 2 ORDER BY second_largest_total DESC;
DeepSeek-V4-Pro: ```sql SELECT c.name, ROUND(o.total_cents / 100.0, 2) AS second_largest_order_dollars FROM customers c INNER JOIN ( SELECT customer_id, total_cents, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY total_cents DESC) AS rn FROM orders ) o ON c.id = o.customer_id WHERE o.rn = 2 ORDER BY second_largest_order_dollars DESC; ```

Model A better satisfies the prompt: it returns one query, excludes customers with fewer than two orders explicitly, and orders correctly by the computed second-largest value. Model B is mostly correct but includes Markdown fences despite the instruction to return only SQL and is less explicit about the fewer-than-two-orders requirement. (Order-swapped judge pass: Both queries correctly return each customer's second-highest order total and exclude customers with fewer than two orders via rn = 2, but B is slightly better because it adds a deterministic tie-breaker in the window ordering and is a bit more robust. A is still solid, but its ranking among equal totals is less explicit.)

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.

Kimi-K2.7-Code: ```typescript class LRUCache<K, V> { private cache: Map<K, V>; constructor(private capacity: number) { this.cache = new Map(); } 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; this.cache.delete(lruKey); } this.cache.set(key, value); } } ```
DeepSeek-V4-Pro: ```typescript class LRUCache<K, V> { private capacity: number; private map: Map<K, V>; constructor(capacity: number) { this.capacity = capacity; this.map = new Map<K, V>(); } get(key: K): V | undefined { if (!this.map.has(key)) { return undefined; } const value = this.map.get(key)!; this.map.delete(key); this.map.set(key, value); return value; } set(key: K, value: V): void { if (this.map.has(key)) { this.map.delete(key); } else if (this.map.size >= this.capacity) { const oldestKey = this.map.keys().next().value; this.map.delete(oldestKey); } this.map.set(key, value); } } ```

Both outputs correctly implement an LRU cache using Map insertion order for O(1) get/set in practice, and both follow the instruction to return only the class. They are functionally equivalent, with only minor stylistic differences. (Order-swapped judge pass: Both outputs correctly implement an LRU cache using Map insertion order to achieve O(1) get/set behavior and follow the instruction to return only the class. They are effectively equivalent in quality, with only trivial stylistic differences.)

Matchup powered by OpenRouter.