Вітаємо з отриманням 10000 репутації!


19

Після того як @ MartinBüttner досяг репутації рівно 10 000 , тепер у нас на сторінці користувачів три повні ряди в 10 тисяч користувачів ! Тепер, оскільки ми всі програмісти тут, ми любимо автоматизувати речі, а не робити їх вручну. Ваше завдання полягає в тому, щоб написати програму для автоматичного привітання нових 10k користувачів.

Специфікація

Вхідні дані

Вхідними даними будуть nрядки з пробілами. (Якщо ви хочете, ви можете також взяти один список, розділений комами, пробілами, якщо це зробить ваш код коротшим.) Наприклад:

10 20 30 40 50
15 25 35 45 55
20 30 40 50 60

Або:

10 20 30 40 50,15 25 35 45 55,20 30 40 50 60

Кожен список номерів представляє перелік значень репутації користувачів за один день.

Вихідні дані

Вихід буде однаковою кількістю nрядків (або списком, розділеним комами, однакової довжини). Кожен елемент рядка / списку буде:

  • :D якби був користувач, репутація якого щойно стала> = 10 000.
    • Кілька розділених :Dмісцями, якщо було декілька користувачів, які зустріли або пройшли 10 000 повторень. Наприклад, :D :D :Dдля 3 нових 10k користувачів.
  • :( а потім зупиняти подальший вихід, якщо вхід неоднозначний чи неможливий (докладніше про це в наступному розділі).
  • нічого, якщо жодна з цих умов не відповідає дійсності.

Неоднозначність

Можливо, що введення неоднозначне. Для цілей цього виклику ми припускаємо, що:

  • Репутаційна шапка становить 200 на день, ігноруючи акцепти та приємності тощо, заради виклику.
  • Користувачі можуть не втратити репутацію (знову ж таки для простоти та виклику).

Введення вважається неоднозначним, коли неможливо визначити, які значення репутації відповідають якому користувачеві. Наприклад, у введенні даних 10 20,30 40ви не можете сказати, чи став користувач 10-повторним користувачем 30-повторним або 40-повторним користувачем.

Введення вважається неможливим, коли користувачі з одного дня, можливо, не могли стати користувачами з наступного дня. Наприклад, у введенні даних 10 20,310 320така ситуація явно неможлива, оскільки користувачі не могли набути 300 репутацій за день. Користувачі втратити репутацію також неможливо.

Корпусні кромки

  • Початкові значення репутації можуть починатися з чого завгодно (тобто користувач може починати з репутації 1337).
  • Вихід для першого елемента / списку не існує.
  • Вхід завжди буде синтаксично дійсним, тобто значення репутації завжди будуть цілими цілими числами, завжди буде однакова кількість значень репутації на елемент рядка / списку тощо.
  • Значення репутації не сортуються; вони можуть бути в будь-якому порядку.

Тестові справи

Вхід: 9900,10000
Вихід::D

Вхід: 9900 9950 9910,10100 9950 9910,10300 10150 10110
Вихід::D,:D :D

Вхід: 10 20 30,42 10 20,10 242 20,442 42 10,0 0 0,442 42 10
Вихід:,,,:(

Вхід: 10 20,15 25,15 25
Вихід:,,

Вхід: 9999 9998 9997,10000 9998 9997,10000 10000 9997,10300 10000 10000
Вихід::D,:D,:(

Вхід: 100,90,80,70
Вихід::(

Вхід: 10000 10000 10000 9999,10000 10000 10000 10000,10010 10020 10030 10040
Вихід::D,:(

Вхід: 9999 9998 9997 9996,10196 10197 10198 10199,10399 10199 10197 10196
Вихід::D :D :D :D,


@ MartinBüttner Ах, цього не помічав. Виправлено
Дверна ручка

Перший крок у цьому прикладі також неоднозначний.
Мартін Ендер

1
Тоді як приклад 4 не є неоднозначним.
Мартін Ендер

(i.e. a user can start with 1337 reputation).Мені сподобався цей коз, який був моїм представником ... привіт 5 хвилин тому, поки хтось не схвалив одну з моїх відповідей xD
Teun Pronk

Приклад 5, крок 2 також неоднозначний (який 10k користувач, який?). Те саме стосується прикладу 7 (якщо ви не додасте якесь правило про те, що розпізнавання рівних користувачів репліку не має значення, але як тоді ви дізнаєтесь, хто саме був у той день, якщо згодом він зв’язався з кимось іншим?)
Мартін Ендер

Відповіді:


12

Рубін, 209 байт

Редагувати: я перейшов на Ruby, що скоротило це приблизно на 30%. Перегляньте історію редагування оригінальної версії Mathematica. Я гадаю, що основна економія приходить від того, що Рубі permutationне ігнорує переключені положення однакових елементів (на які мені довелося обдурити Mathematica).

Для цього використовується формат розділеного рядка.

gets.split('
').map{|s|s.split.map &:to_i}.each_cons(2){|a,b|a.permutation.map{|q|q.zip(b).map{|x,y|y-x}}.reject{|d|d.any?{|x|x<0||x>200}}.size!=1?abort(':('):(puts':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))}

Суть у цьому:

  • Отримайте всі пари поспіль.
  • Отримайте всі перестановки попереднього дня і відніміть кожну з них з поточного дня.
  • Викопайте всі результати, які містять відмінні або негативні 200.
  • Якщо кількість перестановок, що залишилися, не дорівнює 1, виведіть :(.
  • В іншому випадку виведіть стільки ж, :Dскільки нових користувачів 10k.
  • Наприкінці киньте всі дні після першого :(.

Менше гольфу:

gets.split("\n").map{|s|
  s.split.map &:to_i
}.each_cons(2){|a,b|
  a.permutation.map{|q|
    q.zip(b).map{|x,y|
      y-x
    }
  }.reject{|d|
    d.any?{|x|
      x<0||x>200
    }
  }.size!=1 ? abort(':(') : (puts ':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))
}

Я думаю, що це один прекрасний ланцюжок перелік. :)

PS: Чи дивно, що я першим на це відповів?


8
Я не думаю, що це дивно. Щось говорить про те, що ти маєш перевагу на домашньому полі;)
Захоплення Кальвіна

Отже, це призведе до невдачі деяких прикладів у питанні, правда?
Cruncher

@Cruncher Не вдасться до тих, що, на мою думку, помиляються відповідно до специфікації (як я вже згадував у коментарях). Якщо Doorknob вирішить змінити специфікацію замість того, щоб фіксувати приклади, я думаю, мені доведеться це переробити.
Мартін Ендер

@ MartinBüttner Це я зрозумів. Щойно підтверджую :)
Cruncher

6

Хаскелл, 254 249 244 232 228

import Data.List
t=m(9999<)
p(a:b:r)=(a,b,r)%(filter(all(`elem`[0..200]))$nub$m(zipWith(-)b)$permutations a)
p _=""
(a,b,r)%(_:[])=(concat$m(const":D ")$t b\\t a)++'\n':p(b:r)
_%_=":("
m=map
main=interact$p.m(m read.words).lines

Невелике пояснення: алгоритм дуже схожий на той, який використовував MartinBüttner, за винятком того, на nubякий я витратив певну думку. Зверніть увагу , що різниця список використовується для роботи, скільки більш репутації значення 10000 або більше в день п + 1 по порівнянні з днем п: t b\\t a.

Я також погоджуюся з Мартином Бюттнером щодо тлумачення специфікацій, і що деякі з наведених вище прикладів є помилковими, навіть до того, що приклад №2 є неправильним (повинен бути :().


Ви не повинні мати псевдонім map?
гордий haskeller

1
Це правильно (збереження 2 байтів), але ще 10 байт можна зберегти, зробивши zінфікс та замінивши replicate (length l) xна map (const x) l. Хіба не Haskell фантастично?
TheSpanishInquisition

це точно. Приємного гольфу! На цій ноті, бо застосування функції має найвищий пріоритет, ви повинні бути в змозі скоротити (t b)\\(t a)до t b\\t a, грати в гольф з ще 4 байта.
гордий haskeller

Було б добре, якби якийсь код знайшов ці місця, де код можна скоротити автоматично ... Хоча проект здається трохи більшим.
гордий haskeller

Ви маєте рацію @proudhaskeller, ці паретеси були не потрібні. Спасибі.
TheSpanishInquisition
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.