Моє слово може побити ваше Слово


26

ПРОБЛЕМА

Давши два слова, знайдіть переможця у цифровій кореневій битві.

Визначте цифровий корінь слова таким чином:

  1. Кожній букві алфавіту присвоюється число: A = 1, B = 2, C = 3, ..., Z = 26
  2. Додайте значення для кожної літери до загальної кількості слова. Візьміть, наприклад, "CAT". C + A + T = 3 + 1 + 20 = 24
  3. Додайте всі одиничні цифри, які складають цей результат: 24 => 2 + 4 = 6
  4. Повторіть крок №3, поки не досягнете однієї цифри. Ця однозначна цифра - це цифровий корінь слова.

Правила:

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

Спеціальні правила:

  1. Не дозволяється використовувати модуль для обчислення цифрового кореня . Його можна використовувати де завгодно.
  2. Припустимо, слова складаються лише з великих літер - без розділових знаків, без пробілів тощо.

ВХОД

Проведіть слова через stdin (розділені комами). параметрів методу, або як би ви хотіли. У вашому рішенні чи коді з’ясуйте, як розбираються чи готуються слова.

ВИХІД

Покажіть слово-переможець. Якщо переможця немає, виведіть "STALEMATE".

Приклади:

Вхід: CAN, BAT

CAN = 18 = 9
BAT = 23 = 5 

вихід: CAN

вхід: ZOO, NO

ZOO = 56 = 11 = 2
NO = 29 = 11 = 2

OO = 30 = 3
N = 14 = 5

вихід: НІ

ОНОВЛЕННЯ : Введення потрібно читати за допомогою stdin із словами як розділений комою рядок.

ОНОВЛЕННЯ : Додано кілька прикладів для тестування проти.

ОНОВЛЕННЯ : уточнено видалення найціннішого письма у випадку краватки - це також трохи змінює умову зупинки - якщо слово має одну літеру або нульову літеру, процес скорочення зупиняється


Ви повинні визначитися з входом, не залишати його на вибір, оскільки це робить величезну різницю в програмах. Вибравши метод введення та провівши його, ви видалите «творчі інтерпретації» та зробите виклик, рівний для всіх.
MtnViewMark

@MtnViewMark - Розуміється, але ефективно я намагаюся видалити читання вхідних даних із кількості символів. Мене не цікавить найрозумніший чи найкоротший спосіб прочитати в двох словах. Якщо потрібний конкретний метод, також є обмеженням певних мов - я думаю, я просто намагаюся зрозуміти проблему.
Стів

1
@Steve - Тоді ви також не повинні визначати вихід як "display", так? Однак, я думаю, ви, можливо, занадто багато усуваєте проблему. Розумний і короткий гольф часто випливає з поєднання різних аспектів проблеми хитромудрими способами, наприклад, складання частини обробки на вхід чи вихід. Щодо мов обмежених можливостей - майже всі вони можуть читати stdin та писати stdout.
MtnViewMark

@MtnViewMark - Справедлива точка. Я зроблю просте оновлення та очищую його. Моя мова вибору просто має тривалий спосіб читання з stdin, тому я переживаю упередженість. :)
Стів

Чи приймає вхідний аргумент для основного рахунку як від stdin? О, і взагалі, якщо ви хочете стримувати вимоги щодо бродячих речей, таких як читання з stdin та необхідність імпорту або включення інших модулів чи файлів, то головоломка потребує функції, а не цілої програми, найпростішим способом може стати проблема. .
Джонатан М Девіс

Відповіді:


9

J, 100

z=:"."0@":@(+/)^:9@(64-~a.i.])@(#~' '&i.)"1
f=:*@-/"2@(z@((]#~]i.~{.@\:~)"1^:([:=/z))){'STALEMATE'&,

працює так:

f 'NO',:'ZOO'
NO       
f 'CAN',:'BAT'
CAN      
f 'FAT',:'BANANA'
FAT      
f 'ONE',:'ONE'
STALEMATE

НЕ все ж приймають вхідні дані точно так , як просили.


9

APL (Діалог) ( 91 86)

⎕ML←3⋄{Z≡∪Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨+/¨⎕A∘⍳¨⍵:G[↑⍒Z]⋄1∊↑¨⍴¨⍵:'STALEMATE'⋄∇1∘↓¨⍵}G←Z⊂⍨','≠Z←⍞

Пояснення (у порядку виконання):

  • ⎕ML←3: встановіть ML на 3 (це означає, серед іншого, розділ).
  • G←Z⊂⍨','≠Z←⍞: читати введення, розділяти комами, зберігати в G та переходити до функції.
  • +/¨⎕A∘⍳¨⍵: обчисліть бал за кожне слово. ( ⎕Aце список, що містить алфавіт.)
  • Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨: обчисліть цифровий корінь для кожного балу (підсумовуючи всі цифри, поки є ще одна цифра) і зберігайте їх у Z.
  • Z≡∪Z: якщо всі бали унікальні ...
  • :G[↑⍒Z]: ... тоді виведіть слово з найбільшою оцінкою (з оригінального списку).
  • ⋄1∊↑¨⍴¨⍵:'STALEMATE': інакше (якщо є краватка), якщо одне зі слів має довжину 1, виведіть STALEMATE.
  • ⋄∇1∘↓¨⍵: в іншому випадку зніміть першу букву з кожного слова та запустіть функцію ще раз.

5

Рубін - 210

d,e=(a,b=$<.read.chop.split(/,/)).map{|w|w.bytes.sort}
r=->w,o=65{n=0;w.map{|c|n+=c-o};n>9?r[n.to_s.bytes,48]:n}
d.pop&e.pop while r[d]==r[e]&&d[1]&&e[1]
$><<[[:STALEMATE,a,b][a.size<=>b.size],a,b][r[d]<=>r[e]]

Тести:

$ ruby1.9 1128.rb <<< CAN,BAT
CAN

$ ruby1.9 1128.rb <<< ZOO,NO
NO

$ ruby1.9 1128.rb <<< ZOO,ZOO
STALEMATE

Перший рядок можна скоротити до d,e=(a,b=gets.split ?,).map{|w|w.bytes.sort}.
Вентеро

Чому б не скоротити це далі, використовуючи якесь інше слово для позначення краватки? тобто "TIE" проти "STALEMATE"
Gaffi

@Gaffi, оскільки специфікація вимагає використовувати слово "STALEMATE".
Пол Престиждж

@chron Сором мені, я перестав читати о"If the words are of equal length and no winner is found after going through the shortening process, no winner is declared."
Гаффі

5

Haskell, 205 символів

import List
s b=d.sum.map((-b+).fromEnum)
d q|q<10=q|1<3=s 48$show q
f=map(s 64.concat).tails.group.reverse.sort
w(a,_:b)=f a#f b where x#y|x<y=b|x>y=a|1<3="STALEMATE"
main=getLine>>=putStrLn.w.span(/=',')

Проби:

> ghc --make WordVsWord.hs 
[1 of 1] Compiling Main             ( WordVsWord.hs, WordVsWord.o )
Linking WordVsWord ...

> ./WordVsWord <<< CAN,BAT
CAN

> ./WordVsWord <<< ZOO,NO
NO

> ./WordVsWord <<< FAT,BANANA
FAT

> ./WordVsWord <<< ONE,ONE
STALEMATE

  • Редагувати: (227 -> 219) кращий вибір переможця, скорочена відповідність візерунка w, імпортний старший, коротший модуль
  • Редагувати: (219 -> 208) Включіть пропозиції JB
  • Редагувати: (208 -> 205) обробляти негативні числа, використовуючи непарні правила в Haskell про дефіс

1
Використання прямого списку порівняння - дуже приємний штрих. Кілька запропонованих «оглядових» удосконалень: ',':b_:b(-2), якщо ви не надто прихильні до багаторядкової обробки interact$unlines.map([...]).linesputStr.[...]=<<getLine(-11), якщо ви дозволяєте собі скоротити вихід putStrprint(-1). Я ненавиджу те, що операція заперечення забирає стільки символів, але не можу знайти шлях.
JB

Дякую, JB! Я включив більшість пропозицій. Я відчував, що вихід повинен слідувати специфікації, зокрема закінчуватися новим рядком. Але я був би готовий зберегти ці два персонажі, якщо він наблизиться! :-)
MtnViewMark

Гарна робота з відніманнями!
JB

3

Перл, 224 225 229

Основний гольф (ще нічого розумного):

split",",<>;$_=[sort map-64+ord,/./g]for@a=@_;{for(@b=@a
){while($#$_){$s=0;$s+=$_ for@$_;$_=[$s=~/./g]}}($a,$b)=
map$$_[0],@b;if($a==$b){pop@$_ for@a;@{$a[1]}*@{$a[0]}&&
redo}}say+("STALEMATE",@_)[$a<=>$b||@{$a[0]}<=>@{$a[1]}]

Perl 5.10 і вище, запустіть з perl -M5.010 <file>абоperl -E '<code here>'

$ perl -M5.010 word.pl <<<CAN,BAT
CAN
$ perl -M5.010 word.pl <<<ZOO,NO
NO

$ perl -M5.010 word.pl <<<NO,ON
STALEMATE

2

К, 106

{a::x;@[{$[(>). m:{+/"I"$'$+/@[;x].Q.A!1+!26}'x;a 0;(<). m;a 1;.z.s 1_'x@'>:'x]};x;"STALEMATE"]}[","\:0:0]

Використовує обробку винятків для лову помилок стека, що призводить до випадків похилого стану.


2

VBA ( 242 462)

Function s(q,Optional l=0)
s=-1:t=Split(q,","):r=t:m=t
For j=0 To 1
m(j)=0:w=t(j)
While Len(w)>1 Or Not IsNumeric(w)
b=0
For i=1 To Len(w)
a=Mid(w,i,1):a=IIf(IsNumeric(a),a,Asc(a)-64):b=b+a
If m(j)+0<a+0 Then m(j)=a
Next
w=b
Wend
r(j)=b
Next
s=IIf(r(0)>r(1),0,IIf(r(0)<r(1),1,s))
For j=0 To 1
r(j)=Replace(t(j),Chr(m(j)+64),"",,1)
Next
If s<0 And Len(t(0))+Len(t(1))>2 Then s=s(r(0) & "," & r(1),1)
If l=0 Then If s>=0 Then s=t(s) Else s="STALEMATE"
End Function

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

Оригінал (внизу) не вилучив найвищу букву зі слів, коли була краватка.

Sub s(q)
t=Split(q,",")
r=t
For j=0 To 1
w=t(j):b=0
For i=1 To Len(w)
b=b+Asc(Mid(w,i,1))-64
Next
While Len(b)>1
d=0
For i=1 To Len(b)
d=d+Mid(b,i,1)
Next
b=d
Wend
r(j)=b
Next
MsgBox IIf(r(0)>r(1),t(0),IIf(r(0)<r(1),t(1),"STALEMATE"))
End Sub

2

Це дійсно захопило мене і це моє перше повідомлення. Хоча вона стара, я помітив, що ніхто не робив php-версію, ось ось моя.

<?php $f='CAN,CBN';$w=explode(',',$f);$a=$ao=$w[0];$b=$bo=$w[1];$c='';
function splice($a,$t){$s=$h=0;$y=array();$x=str_split($a);
foreach($x as $k=>$v){$s=$s+ord($v)-64;if($v>$h){$h=$k;}}
$y[0]=$s;if($t==1){unset($x[$h1]);$y[1]=$x;}return $y;}
while($c==''){$y1=splice($a,0);$y2=splice($b,0);$y3=splice($y1[0],1);
$y4=splice($y2[0],1);if($y3[0]>$y4[0]){$c=$ao;}else if($y3[0]<$y4[0]){$c=$bo;
}else if((strlen($a)<1)OR(strlen($b)<1)){if(strlen($a)<strlen($b)){$c=$ao;}
else if(strlen($b)<strlen($a)){$c=$bo;}else{$c='STALEMATE';}}}
echo $c;
?>

534 персонажів.

Тепер я не впевнений у правилах початку, тому я почав з $ f = 'CAN, CBN' як свого вкладу. Я сподіваюся, що це було правильно. Я провів усі тести, і всі вони проходять, хоча це не особливо елегантно. Я справді повинен трохи поспати, але мені це було весело, працюючи над цим - дякую за чудову головоломку.

Зашифровано на http://codepad.org/ZSDuCdin


Ви можете використовувати $f=trim(fgets(fopen('php://stdin')));для отримання даних.
Електра

Подряпайте це, $w=fgetcsv(STDIN);працює краще.
Електра

1

Д: 326 персонажів

import std.algorithm,std.array,std.conv,std.stdio;void main(string[]a){alias reduce r;auto b=array(splitter(a[1],","));auto s=map!((a){int n=r!"a+b"(map!"cast(int)(a-'A')+1"(a));while(n>9)n=r!"a+b"(map!"cast(int)(a-'0')"(to!string(n)));return n;})(b);int v=r!"a>b?a:b"(s);writeln(count(s,v)>1?"STALEMATE":b[countUntil(s,v)]);}

Більш розбірливо:

import std.algorithm, std.array, std.conv, std.stdio;

void main(string[] a)
{
    alias reduce r;

    auto b = array(splitter(a[1], ","));
    auto s = map!((a){int n = r!"a + b"(map!"cast(int)(a - 'A') + 1"(a));

                      while(n > 9)
                          n = r!"a+b"(map!"cast(int)(a - '0')"(to!string(n)));

                      return n;
                     })(b);
    int v = r!"a > b ? a : b"(s);

    writeln(count(s, v) > 1 ? "STALEMATE" : b[countUntil(s, v)]);
}

1

Математика

Деякі деталі все ще відсутні

a = {"ZOO"}; b = {"NO"}
f = FixedPoint[IntegerDigits@Total@# &, #] &

If[(s = f /@ 
        NestWhile[(# /. Max@# -> 0 &) /@ # &, (ToCharacterCode @@ # - 64) & /@ #, 
        f[#[[1]]] == f[#[[2]]] &, 1, 5] &@{a, b})[[1, 1]] > s[[2, 1]], 
   a, b, "STALMATE"]  

{"NO"}

1

Математика 220 207

Написавши це, я помітив, що це випливає з тих же міркувань, якими користувався Велізарій,

h@u_ := ToCharacterCode@u - 64;
m@w_ := FromCharacterCode[Most@Sort@h@w + 64];
f@v_ := FixedPoint[Tr@IntegerDigits@# &, Tr@h@v];
x_~g~y_ := If[f@x == f@y, g[m@x, m@y], If[f@x > f@y, 1, 2]];
x_~z~x_ := "STALEMATE";
x_~z~y_ := {x, y}[[x~g~y]] 

Використання

z["ZOO", "NO"]
z["CAN", "BAT"]
z["FAT", "BANANA"]
z["ONE", "ONE"]

результати

Оскільки відповідь не є конкурентоспроможною (будучи настільки довгостроковою), я вирішив використовувати формат введення, більш прихильний до Mathematica.


1

CoffeeScript - 335

z=(a,b,g=a,h=b)->c=y a;d=y b;e=a.length;f=b.length;return g if(c>d);return h if(d>c);return g if(e<2&&f>1);return h if(f<2&&e>1);return "STALEMATE" if(f==e&&f<2);z(x(a),x(b),a,b)
y=(a)->t=0;t+=c.charCodeAt(0)-1 for c in a;t-=9 while 9<t;t
x=(a)->for i in[90..65]
 b=new RegExp(String.fromCharCode(i));return a.replace b, "" if b.test a

Не настільки задоволений цим, як я міг би бути, але все одно я це викладу. Фактичне оцінювання є дуже стислим ( yфункція), але ifпорівняння результатів (в z) отримує досить довго.

Щоб використовувати це, дзвоніть zдвома словами (наприклад z 'FOO','BAR'). Він оцінить обидва слова і поверне вище бальне слово. Якщо це краватка, вона буде повторюватися з модифікованими словами (зберігаючи оригінали, щоб повернутися в кінцевому підсумку, отже, додаткові два параметри), які вона отримує відx функції.

Еквівалентний (розширений) javascript для зацікавлених:

var x, y, z;

z = function(a, b, g, h) {
  var c, d, e, f;
  if (g == null) {
    g = a;
  }
  if (h == null) {
    h = b;
  }
  c = y(a);
  d = y(b);
  e = a.length;
  f = b.length;
  if (c > d) {
    return g;
  }
  if (d > c) {
    return h;
  }
  if (e < 2 && f > 1) {
    return g;
  }
  if (f < 2 && e > 1) {
    return h;
  }
  if (f === e && f < 2) {
    return "STALEMATE";
  }
  return z(x(a), x(b), a, b);
};

y = function(a) {
  var c, t, _i, _len;
  t = 0;
  for (_i = 0, _len = a.length; _i < _len; _i++) {
    c = a[_i];
    t += c.charCodeAt(0) - 1;
  }
  while (9 < t) {
    t -= 9;
  }
  return t;
};

x = function(a) {
  var b, i, _i;
  for (i = _i = 90; _i >= 65; i = --_i) {
    b = new RegExp(String.fromCharCode(i));
    if (b.test(a)) {
      return a.replace(b, "");
    }
  }
};

1

Ракетка 479 байт

(define(dl n)(let p((ol '())(n n))(let-values(((q r)(quotient/remainder n 10)))(if(= q 0)(cons r ol)(p(cons r ol)q)))))
(define(dr N)(let p2((n N))(define s(apply +(dl n)))(if(< s 10)s(p2 s))))
(let p3((l(for/list((i(string->list s)))(-(char->integer i)64)))(k(for/list((i(string->list t)))(-(char->integer i)64))))
(let((a(dr(apply + l)))(b(dr(apply + k))))(cond[(> a b)s][(< a b)t][(equal? l k)"STALEMATE"][else(p3(remove*(list(apply max l))l)(remove*(list(apply max k))k))])))

Безголівки:

(define (f s t)

  (define (getDigitList n)                     ; sub-fn  to get digit list
    (let loop ((ol '())
               (n n))
      (let-values (((q r) (quotient/remainder n 10)))
        (if (= q 0) (cons r ol)
            (loop (cons r ol) q)))))

  (define (digit_root N)                       ; sub-fn to get digital root of a number
    (let loop2 ((n N))                        
      (define s (apply + (getDigitList n)))    
      (if (< s 10)
          s
          (loop2 s))))

  (let loop3 ((l (for/list ((i (string->list s)))  ; actual fn to compare 2 strings
                   (- (char->integer i) 64)))
              (k (for/list ((i (string->list t)))
                   (- (char->integer i) 64))))
    (let ((a (digit_root (apply + l)))
          (b (digit_root (apply + k))))
      (cond
        [(> a b) s]
        [(< a b) t]
        [(equal? l k) "STALEMATE"]
        [else (loop3 (remove* (list (apply max l)) l)
                     (remove* (list (apply max k)) k)
                     )]
        ))))

Тестування:

(f "CAN" "BAT")
(f "ZOO" "NO")

Вихід:

"CAN"
"NO"

1

PHP, 339 (не для спец.), 410 382 359 339 337 байт

$b=$w=fgetcsv(STDIN);function a($c){for(;a&$g=$c[$p++];)$f+=ord($g)-64;$f=trim($f);for(;$f[1]&a;$f=$h)for($h=0;a&$r=$f[$q++];$h=bcadd($h,$r));return$f;}function d($f){return strtr($f,[max(str_split($f))=>'']);}for(;$c==$d;$b=[$e,$f]){$x=$z++?d:trim;$e=$x($b[0]);$f=$x($b[1]);$c=a($e);$d=a($f);$e||die(STALEMATE);$c!=$d&&die($w[$c<=$d]);}

EDIT 1 : +71 байт. Використання STDINзамість fopen('php://stdin','r');та коротких тегів. Крім того, повна відповідність специфікації.

EDIT 2 : -28 байт. Використання fgetcsv(STDIN)замість explode(',',trim(fgets(STDIN))), а forзамість whileциклу використовується цикл.

EDIT 3 : -23 байти. Об'єднані функції aі b, об'єднані для циклів.

EDIT 4 : -20 байт. Перетворився cз рекурсивного в цикл. Потім вилучили функцію cі ввели її код у глобальний простір імен.

EDIT 5 : -2 байти. Дякуємо @Titus за -rпрапор.


1
немає необхідності в тезі PHP з -rпрапором
Titus

0

JAVA

    public static void main(String args[]) throws Exception{
        String input=(new BufferedReader(new InputStreamReader(System.in)).readLine());
        StringTokenizer st = new StringTokenizer(input, ",");
        String w1 = st.nextToken();String w2 = st.nextToken();int s1=0;int s2=0;
        String flag="";
        do{ Integer sum1=0;Integer sum2=0;
        for (int i=0;i<w1.length();i++)
            sum1+=((int)w1.charAt(i) - 64);
        for (int i=0;i<w2.length();i++)
            sum2+=((int)w2.charAt(i) - 64);
        while (sum1.toString().length()>1){
            s1=0;
            for (int i=0;i<sum1.toString().length();i++)
                s1+=((int)sum1.toString().charAt(i)-48);
            sum1=s1;
        }
        while (sum2.toString().length()>1){
            s2=0;
            for (int i=0;i<sum2.toString().length();i++)
                s2+=((int)sum2.toString().charAt(i)-48);
            sum2 =s2;
        }
        flag=(s1>s2)?w1:(s1!=s2)?w2:"";
        if (flag!="")
            {st = new StringTokenizer(input,",");
                if (s1>s2)
                    System.out.println(st.nextToken());  
                else{
                    st.nextToken();
                    System.out.println(st.nextToken());
                }
            }
        int max=0;
        for (int i=0;i<w1.length();i++){
            max=((int)w1.charAt(i)>max)?(int)w1.charAt(i):max;
        }
        w1 = w1.replace((char)max, (char)64);
        max=0;
        for (int i=0;i<w2.length();i++){
            max=((int)w2.charAt(i)>max)?(int)w2.charAt(i):max;
        }
        w2 = w2.replace((char)max, (char)64);
            }while(flag=="" && !w1.equals(w2)); 
    if (flag.length()<1)
        System.out.println("STALEMATE");
        }

Код, наведений вище, замінює всі символи максимуму на випадок краватки. Це потрібно?
Aman ZeeK Verma

0

C ++, 473 (я позичаю залізо курсу)

#include<iostream>
#define $ string
#define _ return
using namespace std;$ S($&s){int i=-1,m=i,x=0;while(++i<s.length())if(s[i]-'@'>x)m=i,x=s[i];s.erase(m,1);_ s;}int M($ w){int i,v=0;for(i=0;i<w.length();++i)v+=w[i]-'@';while(v>9){i=0;while(v)i+=v-v/10*10,v/=10;v=i;}_ v;}$ B($ x, $ y){while(!(M(x)-M(y)))S(x),S(y);if(M(x)>M(y))_ x;if(M(x)<M(y))_ y;_"STALEMATE";}int main(int c,char**v){$ s;cin>>s;$ x=s.substr(0,s.find(',')),y=s.substr(s.find(',')+1);cout<<B(x,y)<<endl;_ 0;}

Я впевнений, що міг би якось скоротити його, але я втомився.

Редагувати: спочатку брав аргумент командного рядка, модифікований для використання cin. Напевно, зараз на кілька персонажів більше, але я занадто втомився, щоб перерахувати це.


0

Пітон: 383 символів

запустити функцію c('CAN','BAT'):

def k(j):
 l=list(j);l.remove(max(j));return''.join(l)
def f(x):
 x=str(x)
 if len(x)==1 and x.isdigit():return int(x)
 return f(sum('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.index(y)+1 for y in x)) if x.isalpha() else f(sum(map(int,x)))
def c(a,b):
 v=f(a);u=f(b);
 if v>u:return a
 if v<u:return b
 return'STALEMATE' if v==u and (len(a)==1 or len(b)==1)else c(k(a),k(b))

0

F #, 559 533 530 байт

Поки що не конкурентоспроможний. Я впевнений, що c можна скоротити, як і останні кілька рядків. Тут не шкодить і простіший доступ до аргументів командного рядка.

open System
let m=Seq.map
let a s=s="";s.ToUpper()|>m(fun c->int c-64)
let rec c i=if i>9 then string i|>m(int>>(-))|>m(fun x->x 48)|>Seq.sum|>c else i
let b i=Seq.fold(fun(r,a)j->(Seq.sum i-a)::r,a+j)([],0)(Seq.sortBy(~-)i)|>fst|>m c
[<EntryPoint>]
let x z=
 let y=z.[0].Split(',')
 let u,v=y.[0].Length,y.[1].Length
 printf"%s"(Seq.fold2(fun s l r->if l=r then 3::s else if l>r then 0::s else 1::s)[](b<|a y.[0])(b<|a y.[1])|>Seq.tryFind((>)3)|>function|None when u>v->y.[0]|None when u<v->y.[1]|Some x->y.[x]|_->"STALEMATE")
 0

Спробуйте в Інтернеті!

  • Збережено 3 байти шляхом обмеження s до рядка, порівнявши його з рядком

Безгольова версія

open System
let m=Seq.map // this is just to save some characters and I'll use Seq.map for this version

let toIntList s =
    s = "" // constrain s to type string
    s.ToUpper()
    |>Seq.map (fun c -> int c - 64) // converts char value to int and offsets it so that A=1

let rec digitSumUntilSingle i =
    if i > 9 then
        string i                // convert number to string
        |>Seq.map ( int>>(-) )  // convert individual char to int and partially apply substraction
                                // this returns a function
        |>Seq.map (fun x -> x 48) // provide last parameter for substraction, this is equivalent to
                                  // charValue - 48
        |>Seq.sum                 // sum over all digits
        |>digitSumUntilSingle     // recursively call this function again in case we are >9
    else
        i

let calculateDigitalRoot input =
    Seq.fold(fun (result, acc) current ->       // calculate digital root for all possible iterations
                (Seq.sum input - acc)::result,  // basically, this calculates Rule 3 until the end for a given word
                acc + current
            ) ([], 0) (Seq.sortBy (~-) input) // sort input by value descending
    |>fst   // only interested in the lits, not the final accumulator
    |>Seq.map digitSumUntilSingle

[<EntryPoint>]
let main (args) =
    let y = args.[0].Split(',')
    let leftLength = y.[0].Length
    let rightLength = y.[1].Length

    Seq.fold2 (fun state left right ->
                if left = right then
                    3::state
                else if left > right then
                    0::state                // 0 is chosen because this represents y[0] index
                else
                    1::state
               ) [] (calculateDigitalRoot (toIntList y.[0])) (calculateDigitalRoot (toIntList y.[1]))
    |> Seq.tryFind ((>) 3)                  // try to find first variation where left and right digital root isn't equal
    |> function
        | None when leftLength > rightLength -> y.[0]
        | None when leftLength < rightLength -> y.[1]
        | Some x -> y.[x]
        | _ ->"STALEMATE"
    |>printf "%s" 
    0

0

PHP, 296 281 267 байт

function f(&$s){for(;$c=$s[$i++];$m>$c||$m=$c)$p+=ord($c)&31;for($s=str_replace($m,'',$s);9<$p=array_sum(str_split($p)););return$p;}for(list($a,$b)=$x=fgetcsv(STDIN);$s==$t&&$a&$b;$t=f($b))$s=f($a);echo($s-=$t)||($s=strlen($x[0])-strlen($x[1]))?$x[+($s<0)]:STALEMATE;

запустіть -nабо спробуйте його в Інтернеті (TiO включає поломку).

Ще у лютому 2011 року поточна версія PHP склала 5.3.5; тому я не міг

  • використовувати призначення скороченого списку ( [$a,$b]=fgetcsv(...)і таке)
  • псевдонім count_charsрядковий
  • Функція індексу безпосередньо результати
  • використовувати негативні рядкові індекси замість substr

Але жодне б не врятувало багато; тому це не має великого значення

Найбільш дорогими речами були петлі (звичайно) і правило №4 ( 40 36 байт).

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