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


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*⍵-3)×60*+\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.