Граф, як вавилонянин


41

Виклик

Враховуючи ASCII подання вавілонського числа як вхідного, виведіть це число західноарабськими цифрами.

Вавілонська система числення

Як рахували вавилонян? Цікаво, що вони використовували систему Base 60 з елементом системи Base 10. Розглянемо спочатку одиничний стовпчик системи:

Вавілоняни мали лише три символи: T(або, якщо ви можете їх віддати:), 𒐕який являв собою 1, і <(або, якщо ви можете видати його:), 𒌋який представляв 10, і \(або, якщо ви його висловлюєте:), 𒑊який представляв нуль.

Примітка: Технічно \(або 𒑊) не дорівнює нулю (оскільки вавілоняни не мали поняття «нуль»). «Нуль» був винайдений пізніше, тому \символом-заповнювачем було додано пізніше, щоб запобігти двозначності. Однак для цілей цього виклику достатньо вважати \нулем

Отже, у кожному стовпчику ви просто додаєте значення символів, наприклад:

<<< = 30
<<<<TTTTTT = 46
TTTTTTTTT = 9
\ = 0

Ніколи не буде більше п'яти <чи більше дев'яти Tу кожному стовпчику. \завжди відображатиметься окремо в стовпці.

Тепер нам потрібно поширити це на додавання більше стовпців. Це працює точно так само, як і будь-яка інша база шістдесят, де ви помножите значення крайнього правого стовпця на , лівого на , лівого на тощо. Потім ви додаєте значення кожного, щоб отримати значення числа.600601602

Стовпці будуть розділені пробілами, щоб запобігти двозначності.

Деякі приклади:

<< <TT = 20*60 + 12*1 = 1212
<<<TT \ TTTT = 32*60^2 + 0*60 + 4*1 = 115204

Правила

  • Ви можете прийняти або вхід ASCII ( T<\), або Unicode ( 𒐕𒌋𒑊)
  • Введене число завжди буде менше 107
  • <S завжди буде зліва від Tї в кожному стовпчику
  • \ завжди відображатиметься окремо в стовпці

Перемога

Виграє найкоротший код у байтах.


2
@TaylorScott Так, можливо
Beta Decay

2
У випадку, якщо це допоможе: Макс, який потрібно обробити, - це 4 стовпчики:<<<<TTTTTT <TTTTTTT <<<<TTTTTT <<<<
Wernisch

1
Чи завжди стовпчики розділені рівно одним пробілом ? Я помічаю відповіді, що спираються на це.
KRyan

4
Іноземні типи з кальянними трубами кажуть: Ай-а-а-а-а-а, а-а-а-а-а-а, сі - о, як вавилонський. Чудово. Тепер це застрягло в моїй голові.
кобальтдук

5
"How did the Babylonians count? Interestingly, they used a Base 60 system with an element of a Base 10 system."Який використовується і сьогодні; вавілонська система чисел - саме те, що ми використовуємо для годинників. Дві десяткові цифри кожна секунди, хвилини та години, 60 секунд до хвилини, 60 хвилин до години.
Рей

Відповіді:


39

JavaScript (ES6), 44 байти

Приймає вхід як масив символів ASCII.

a=>a.map(c=>k+=c<1?k*59:c<'?'?10:c<{},k=0)|k

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

Як?

Вавилонську числову систему можна розглядати як 4-інструкційну мову, що працює з єдиним регістром - назвемо її акумулятором.

Починаючи з , кожен символ c у вхідному масиві a модифікує акумулятор k наступним чином:к=0cак

  • space: помножити на 60 (реалізовано як: додати 59 k до k )к6059кк
  • <: Додати до K10к
  • T: приріст к
  • \: нічого не робити; це NOPінструкція з цієї мови (реалізована як: додати до k )0к


11

Perl 6 , 39 байт

-3 байти завдяки nwellnhof

{:60[.words>>.&{sum .ords X%151 X%27}]}

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

Використовує клинописні символи.

Пояснення:

{                                     }   # Anonymous code block
     .words  # Split input on spaces
           >>.&{                    }  # Convert each value to
                sum   # The sum of:
                    .ords # The codepoints
                          X%151 X%27   # Converted to 0,1 and 10 through modulo
 :60[                                ]  # Convert the list of values to base 60

Ти бив мене пару хвилин. Ось що я придумав: {:60[.words>>.&{sum (.ords X%151)X%27}]}(40 байт)
nwellnhof

@nwellnhof Дуже добре! Як ви знайшли модні значення?
Джо Кінг

2
Просто грубою силою.
nwellnhof

11

Желе ,  13  12 байт

ḲO%7C%13§ḅ60

Монадична посилання, що приймає список символів, який дає ціле число.

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

Як?

ḲO%7C%13§ḅ60 - Link: list of characters   e.g. "<<<TT \ TTTT"
Ḳ            - split at spaces                 ["<<<TT", "\", "TTTT"]
 O           - cast to ordinals                [[60,60,60,84,84],[92],[84,84,84,84]]
  %7         - modulo by seven (vectorises)    [[4,4,4,0,0],[1],[0,0,0,0]]
    C        - compliment (1-X)                [[-3,-3,-3,1,1],[0],[1,1,1,1]]
     %13     - modulo by thirteen              [[10,10,10,1,1],[0],[1,1,1,1]]
        §    - sum each                        [32,0,4]
         ḅ60 - convert from base sixty         115204

Ще 12: ḲO⁽¡€%:5§ḅ60( ⁽¡€це 1013, так що це модулі 1013з боку Ordinal значень отримує 53, 5і 1для <, T, \відповідно , а потім викон ють цілочисельне ділення, з :допомогою , 5щоб отримати 10, 1і 0)


Лол, я видалив свою відповідь саме через це, оскільки згадав, що можу використовувати базову конверсію, але був буквально лінивий, щоб дізнатися, як це зробити. +1
Містер Xcoder

6

05AB1E , 13 байт

8740|Ç%4/O60β

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

Щоб компенсувати те, як я лінувався зі своєю відповіддю на Jelly, ось подання в 05AB1E xD.


Допоможіть 05AB1E-і там, хіба не було способу стиснути такі числа, як 8740?
Містер Xcoder

2
codegolf.stackexchange.com/a/166851/52210 На жаль, це не буде коротше: •Yη•(4 байти)
Kevin Cruijssen

2
@KevinCruijssen Дякую! Ця відповідь дуже корисна, я цілком буду її використовувати в майбутньому
містер Xcoder

1
Радий, що підказка корисна. :) Я зрозумів ці речі, побачивши деякі відповіді, використовуючи їх. Словник частина була пояснена тут . І стиснення інших рядків або великих цілих чисел я з'ясував сам, побачивши пов'язаний приклад відповідей на "гусака" і 246060 .
Kevin Cruijssen

1|Ç7%-13%O60βтеж 13 - це гольфа?
Джонатан Аллан

6

Python 2 , 96 93 87 85 байт

lambda s:sum(60**i*sum(8740%ord(c)/4for c in v)for i,v in enumerate(s.split()[::-1]))

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


Збережено:

  • -1 байт, дякую містеру Xcoder
  • -4 байти, завдяки Пуну Леві
  • -2 байти, завдяки Меттью Дженсену

1
95:(ord(c)%5/2or 11)-1
Містер Xcoder

@ Mr.Xcoder Спасибі :)
TFeld

2
87:8740%ord(c)/4
Пун Леві

-2, видаливши дужки навколо другої суми () Спробуйте в Інтернеті!
Меттью Йенсен

@MatthewJensen Дякую :)
TFeld

4

Excel VBA, 121 байт

Обмежений 32-бітним офісом, який ^виконує функцію LongLongлітералу типу в 64-бітних версіях

Здійснює вхід з комірки A1та виводить у вікно безпосереднього вікна.

a=Split([A1]):u=UBound(a):For i=0 To u:v=a(i):j=InStrRev(v,"<"):s=s+(j*10-(InStr(1,v,"T")>0)*(Len(v)-j))*60^(u-i):Next:?s

Безголовний і коментований

a=Split([A1])       '' Split input into array
u=UBound(a)         '' Get length of array
For i=0 To u        '' Iter from 0 to length
v=a(i)              '' Get i'th column of input
j=InStrRev(v,"<")   '' Get count of <'s in input
                    '' Multiply count of <'s by 10; check for any T's, if present
                    ''   add count of T's
t=t+(j*10-(InStr(1,v,"T")>0)*(Len(v)-j))
    *60^(u-i)       '' Multiply by base
Next                '' Loop
?s                  '' Output to the VBE immediate window

4

Діалог APL , 33 30 байт

{+/(⌊10*⍵-360*+\2=⍵}'\ T<'⍳⌽

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

Редагувати: -3 байти завдяки ngn

'\ T<'⍳замінює символи цифрами (їхнє положення у постійній рядку) та обертає вхід, тому останні найбільш значущі "цифри" є останніми. Це дозволяє +\2=зберегти кількість ходу бажаної потужності 60 (застосовано 60*) за рахунок підрахунку кількості разів, де пробіл (індекс 2 у постійній постійній).

⌊10*⍵-3дає бажану потужність десять для кожного персонажа. Порядок символів у рядковій постійній та зсув -3 змушує "\" та пробіл переходити до від'ємних чисел, що призводить до дробів, коли ці символи піднімаються до потужності 10, що дозволяє їх усунути .

Все, що нам зараз потрібно зробити, це помножити цифри потужності на 10 на значення потужності-60 і підбити підсумок партії +/.


збережіть кілька байтів, уникаючи окремого порівняння з ' ':{+/(⌊10*⍵-3)×60*+\2=⍵}'\ T<'⍳⌽
1818



3

APL (NARS ⎕io ← 0), 28 символів, 56 байт

{60⊥{+/⍵⍳⍨10⍴'\T'}¨⍵⊂⍨⍵≠' '}

деякий тест з перевіркою типу:

  q←{60⊥{+/⍵⍳⍨10⍴'\T'}¨⍵⊂⍨⍵≠' '}

  o←⎕fmt
  o q '<< <TT'
1212
~~~~
  o q '<<<TT \ TTTT'
115204
~~~~~~

Кожен тип результату - число.


2

JavaScript (Node.js) , 122 114 107 106 83 байт

a=>a.split` `.map(b=>[...b].map(c=>x+=c<'T'?10:c<'U',x=0)&&x).reduce((a,b)=>a*60+b)

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

Я трохи одержимий операціями з масивом «функціонального стилю», використовує вхід ASCII, наскільки я можу сказати, JS не дуже добре отримує картки з гольфу

Я зберігаю це заради нащадків, але це наївне / німе рішення, я пропоную вам перевірити відповідь Арнаульда, що набагато цікавіше втілення проблеми


@Shaggy схоже, що це працює на мене!
Skidsdev

c<'T'працює замістьc=='<'
пан Xcoder

Збережіть ще 1, замінивши &&на |.
Кудлатий

@Shaggy і економте набагато більше, використовуючи for...ofпетлі: P
лише ASCII

2

Сітківка , 29 26 23 байт

<
10*T
+`^(.*)¶
60*$1
T

Спробуйте в Інтернеті!Використовує розділення нового рядка, але посилання включає в себе заголовок для використання пробілів замість зручності. Редагувати: Збережено 3 байти за допомогою @KevinCruijssen. Збережено ще 3 байти завдяки @FryAmTheEggman. Пояснення:

<
10*T

Замініть кожен < на 10 Tс.

+`^(.*)¶
60*$1

Візьміть перший рядок, помножте його на 60 і додайте наступний рядок. Потім повторюйте, поки не залишиться лише один рядок.

T

Порахуйте T с.

Швидша 51-байтна версія:

%`^(<*)(T*).*
$.(10*$1$2
+`^(.+)¶(.+)
$.($1*60*_$2*

Спробуйте в Інтернеті! Використовує розділення нового рядка, але посилання включає в себе заголовок для використання пробілів замість зручності. Пояснення:

%`^(<*)(T*).*
$.(10*$1$2

Зіставляйте кожен рядок окремо і підраховуйте кількість Ts і 10 разів більше <s. Це перетворює кожен рядок у його базове значення "60 цифр".

+`^(.+)¶(.+)
$.($1*60*_$2*

Базова конверсія 60, запускаючи лінію за один раз. Розрахунок проводиться в десятковій частині для швидкості.


Я впевнений, що третій рядок може бути просто <без +, якщо тільки я не бачу якихось крайових справ.
Kevin Cruijssen

1
@KevinCruijssen Ще краще, як $&зараз завжди один символ, я можу використовувати символ за замовчуванням, зберігаючи ще два байти!
Ніл

Ах приємно! :) Не знав, що це можна зробити неявно для одиноких персонажів.
Кевін Кройсейсен

@KevinCruijssen Ну, мені байдуже, що це за персонаж, оскільки я беру лише довжину; у Retina 1 ви отримуєте деякий _час $*у попередніх версіях Retina за замовчуванням до 1.
Ніл

А, бачу. Ваш початковий код сприймав усі <як один матч і повторював їх у 10 разів більше (кількість <матчу), і запропонована <нами зміна повторюється кожні 10 разів окремо (що ви переграли на 2 байти більше, використовуючи неявний 1 з 10*). Тепер я краще розумію, чому це +було спочатку. Я не знаю надто багато про вбудовані сітківки, лише загально регекси, отже, запропонована нами зміна, тому що я вже читав її як повторення кожні >10 разів. ;)
Кевін Круїссен

2

Bash (з sed і dc), 50 байт

sed 's/</A+/g
s/T/1+/g
s/ /60*/g
s/\\//g'|dc -ez?p

Займає вхід з обмеженим простором stdin, виводить наstdout

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

Пояснення

Використовує sed для перетворення вводу з купою відповідних регулярних виразів, поки, наприклад, вхід <<<TT \ TTTTне трансформується в A+A+A+1+1+60*60*1+1+1+1+. Потім цей вхід подається на dc з явною командою виконання вводу ?, перед якою z(натискає на стек довжину стека (0), щоб у нас десь заземлити додавання) і далі p(print).





1

Вугілля деревне , 26 байт

≔⁰θFS«≡ι ≦×⁶⁰θ<≦⁺χθT≦⊕θ»Iθ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

≔⁰θ

Очистіть результат.

FS«...»

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

≡ι

Переключення поточного символу ...

 ≦×⁶⁰θ

якщо це пробіл, то результат помножте на 60 ...

<≦⁺χθ

якщо це <тоді, додайте 10 до результату ...

T≦⊕θ

якщо це Tпотім приріст результату.

Iθ

Роздрукуйте результат.


1

R , 98 81 байт

(u=sapply(scan(,""),function(x,y=utf8ToInt(x))y%%3%*%(y%%6)))%*%60^(sum(u|1):1-1)

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

Смішно довгий через синтаксичний аналіз. Дякую Джусппе за те, що збрив 16 зайвих байт.

Визначте yзначення байтового коду вводу unicode таR = y("T<\") = y("𒐕𒌋𒑊")

Поспостерігайте за цим R%%3 = 1,2,0і R%%6 = 1,5,0... так R%%3 * R%%6 = 1,10,0!

Решта легко: сума за стовпчиком, потім крапка-добуток із зменшенням потужності 60.


Перенесення Asnawer Arnauld за допомогою зменшення, швидше за все, буде більш гофрованим.
JayCe

не scan(,"")розділяється автоматично на пробіли?
Джузеппе

1
Хороший трюк з модами, хоча! Я намагався розібратися в цьому, але не зміг його знайти ... і /60його можна замінити -1в виразі експонента на інший байт, плюс цей <-може бути замінений, =оскільки це все в дужках.
Джузеппе

@Giuseppe Я спробував %% 3, і це було багатообіцяюче, тому я продовжував шукати ... також за допомогою крапкового продукту просто врятував мені ще один додатковий байт :)
JayCe

1

Рубі , 50 46 байт

->a{x=0;a.bytes{|c|x+=[59*x,10,0,1][c%9%5]};x}

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

Основний порт відповіді Арнальда покращився на GB на -4 байти.


1
45 байт - фактично 47, якщо ви використовуєте "байти" замість "карти"
GB

Спасибі @GB, я, мабуть, дотримуватимуся більш тривалої версії, оскільки вважаючи, що введення даних як необмежених байт-кодів є занадто ліберальним для мови, яка зазвичай підтримує рядки.
Кирило Л.

1
Ще один байт: 46 байт
GB


1

Java 8, 64 60 байт

a->{int r=0;for(int c:a)r+=c<33?r*59:c<63?10:84/c;return r;}

-4 байти завдяки @ceilingcat .

Спробуйте в Інтернеті. Пояснення:

a->{            // Method with character-array parameter and integer return-type
  int r=0;      //  Result-integer, starting at 0
  for(int c:a)  //  Loop over each character `c` of the input-array
    r+=         //   Increase the result by:
       c<33?    //    Is the current character `c` a space:
        r*59    //     Increase it by 59 times itself
       :c<63?   //    Else-if it's a '<':
        10      //     Increase it by 10
       :c<85?   //    Else (it's a 'T' or '\'):
        84/c;   //     Increase it by 84 integer-divided by `c`,
                //     (which is 1 for 'T' and 0 for '\')
  return r;}    //  Return the result

0

Perl -F // -E, 39 байт

$w+=/</?10:/T/?1:/ /?59*$w:0for@F;say$w

Це зчитує число, яке потрібно перетворити з STDIN.

Це важливо те саме рішення, що і @Arnauld, використовуючи JavaScript.


0

F #, 128 байт

let s(v:string)=Seq.mapFoldBack(fun r i->i*Seq.sumBy(fun c->match c with|'<'->10|'T'->1|_->0)r,i*60)(v.Split ' ')1|>fst|>Seq.sum

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

Без вовків це виглядатиме так:

let s (v:string) =
    Seq.mapFoldBack(fun r i ->
        i * Seq.sumBy(fun c ->
            match c with
                | '<' -> 10
                | 'T' ->1
                | _ -> 0
        ) r, 
        i * 60) (v.Split ' ') 1
    |> fst
    |> Seq.sum

Seq.mapFoldBackпоєднує Seq.mapі Seq.foldBack. Seq.mapFoldBackвона повторюється через послідовність назад і передає нитку значення акумулятора через послідовність (у цьому випадку i).

Для кожного елемента в послідовності обчислюється вавилонське число (по Seq.sumBy, яке відображає кожен символ на число і підсумовує результат), а потім помножується на i. iпотім множиться на 60, і це значення потім передається наступному пункту в послідовності. Початковий стан для акумулятора - 1.

Наприклад, порядок дзвінків та результатів Seq.mapFoldBackдля введення <<<TT \ TTTTбуде таким:

(TTTT, 1)     -> (4, 60)
(\, 60)       -> (0, 3600)
(<<<TT, 3600) -> (115200, 216000)

Функція поверне кортеж seq<int>, int. fstФункція повертає перший елемент в цьому наборі, і Seq.sumробить фактичне підсумовування.

Чому б не використовувати Seq.mapiчи подібне?

Seq.mapiвідображає кожен елемент у послідовності та надає індекс функції відображення. Звідти ви могли б зробити 60 ** index(де **енергооператор у F #).

Але **вимагає floats, ні ints, це означає, що вам потрібно або ініціалізувати, або передати всі значення функції як float. Вся функція поверне a float, що (на мою думку) трохи безладно.

Використання Seq.mapi його, можна виконати так для 139 байтів :

let f(v:string)=v.Split ' '|>Seq.rev|>Seq.mapi(fun i r->Seq.sumBy(fun c->match c with|'<'->10.0|'T'->1.0|_->0.0)r*(60.0**float i))|>Seq.sum

0

Tcl , 134 байти

proc B l {regsub {\\} $l 0 l
lmap c [lreverse $l] {incr s [expr 60**([incr i]-1)*([regexp -all < $c]*10+[regexp -all T $c])]}
expr $s}

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

У зворотному списку я циклічно збільшуючи результат підрахунку < та T-allопцією regexp) та збільшуючи натуральну як потужність 60.

Правильна версія (див. Коментар)


Здається, я не зміг цього, через \ в останньому номері ... я мав би regsub {\\} $l0 lперед циклом foreach ....
david

0

APL (Dyalog Extended) , 18 байт SBCS

Функція анонімного негласного префікса.

60⊥10⊥¨≠'<T'∘⍧¨⍤⊆⊢

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

                  ⊢  the argument; "<<<TT \ TTTT"
       ≠             mask where different from space; [1,1,1,1,1,0,1,0,1,1,1,1]
                ⊆    enclose runs of 1; ["<<<TT","\","TTTT"]
               ⍤     on that
              ¨      for each one
             ⍧       Count the occurrences In it of the elements
            ∘        of the entire list
        '<T'         ["<","T"]; [[3,2],[0,0],[0,4]]
      ¨              for each one
   10⊥               evaluate as base-10 digits
60⊥                  evaluate as base-60 digits

0

05AB1E (спадщина) , 10 байт

#Ç9%5BO60β

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

#               # split input on spaces
 Ç              # convert each character to its codepoint
  9%            # modulo 9 (maps 𒌋 to 5, 𒐕 to 1, 𒑊 to 0)
    5B          # convert each to base 5 (5 becomes 10, 0 and 1 unchanged)
      O         # sum each column
       60β      # convert from base 60

05AB1E , 11 байт

#Ç9%5B€O60β

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

Той самий алгоритм, але в сучасному 05AB1E Oне працює над списками змішаних int та списків, тому нам потрібно €Oзамість цього.

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