Определить базу, где данное уравнение истинно

22

Учитывая 3 целых числа, определите наименьшую возможную основу для умножения первых двух целых чисел на третье. Если вы думаете об ответе на главный вопрос жизни, Вселенной и всего остального, 6 * 9 == 42 верно в Базе 13.

Входные данные могут включать любые числа, цифры которых используют символы 0-9, az и AZ, где aравняется 10 в Base 10 и Z61 в Base 10.

Входные данные должны вводиться любым удобным для вас способом (кроме жесткого кодирования), и вы можете написать либо отдельную функцию, либо всю программу.

Максимальная база, которая должна быть рассмотрена, - База 62, а минимальная база - База 2.

Можно предположить, что первые два значения меньше третьего. Можно также сделать вывод, что минимальное основание на единицу больше, чем самая высокая цифра / символ из входов (например, если это входы 3 1a 55, минимальное основание будет основанием 11, поскольку aэто самая высокая цифра).

Если такой базы нет, верните ненужное значение по вашему выбору.

Это код гольф, поэтому выигрывает самый короткий код.

Тестовые случаи

6 9 42     -->   13
a a 64     -->   16
aA bB 36jk -->   41
2 3 20     -->   <junk value>
10 10 100  -->   2
erdekhayser
источник
Я думаю, что STDIN, вероятно, будет лучше, и любой из них будет в порядке.
эрдехайсер
@ MartinBüttner Так я должен просто разрешить ввод в любой форме?
эрдехайсер
1
В качестве пояснения, что следует сделать, если допустимо несколько баз, например, ваш последний пример (который был удален - это было 10 * 10 = 100), где он также действителен для базы 10 и действительно для любой другой базы, к которой вы обращаетесь упомянуть ...
Крис
1
@Kay Если я определяю позиционную систему в базе bв общем виде, например a_0 b^0 + a_1 b^1 + a_2 b^2 + ...(где a_0наименее значимая цифра), то база 1 определенно имеет смысл. Кроме того, заключение ОП будет также включать базу 1 в поиске, если наибольшая существующая цифра равна 0.
Мартин Эндер,
2
О базе 1, унарный - это система счисления. en.m.wikipedia.org/wiki/Unary_numeral_system
эрдехайсер,

Ответы:

3

CJam, 52 51 48 байтов

63,{_ea{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#

Проверьте это здесь. Онлайн тестер не поддерживает ввод через ARGV. Ближайшая альтернатива - поместить ввод как 6 9 42в STDIN и использовать:

lS/:E;
63,{_E{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#

Это печатается, -1если не может быть найдена действительная база до 62.

Большое спасибо Питеру за разбор кода!

Я исправил много проблем, которые добавили 14 байтов к счету. Следующее объяснение все еще для моего первоначального представления, и я обновлю его завтра.

63,{_ea{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#
63,                                              "Push the array [0 1 .. 62].";
   {                                          }# "Find the first index for which the block returns
                                                  a truthy value.";
    _                                            "Duplicate the current base.";
     ea                                          "Read ARGV into an array of strings.";
       {                        }f%              "Apply this block to each character.";
        i32b                                     "Convert to code point, and then to base-32. The
                                                  most significant digit now identifies the 'type'
                                                  of digit.";
            ~\(                                  "Unwrap the array. Swap the digits. Decrement.";
               [G-35-9]                          "Push array [16 -35 -9] of digit offsets.";
                       =-                        "Select the relevant offset and subtract it from 
                                                  the least significant digit.";
                         _                       "Duplicate the current digit D.";
                          Xe>:X;                 "X := max(X,D). X is predefined as 1.";
                                   fb            "Convert all numbers to the current base.";
                                     W%          "Reverse the list of numbers.";
                                       ~         "Unwrap the array.";
                                        *=       "Multiply factors. Check equality with product.";
                                          \      "Swap result with current base.";
                                           X>    "Ensure base is greater than X.";
                                             *   "Multiply boolean results.";

Индекс печатается автоматически в конце программы.

Мартин Эндер
источник
В GS цифры могут быть проанализированы как 32base~\[-16.35 9]=+. Я знаю, что у CJam более короткое базовое преобразование.
Питер Тейлор
7

APL (Dyalog Unicode) , 30 байтов SBCS

⊢{3e=×/2e←⍵⊥⍺:⍵⋄⍺∇⍵+1}1+⌈/∘,

Попробуйте онлайн!

Спасибо Адаму за помощь.

Объяснение:

⊢{3e=×/2e←⍵⊥⍺:⍵⋄⍺∇⍵+1}1+⌈/∘,  
                               left argument ⍺: the vector (do nothing)
                        1+⌈/∘,  right argument ⍵: our starting base.
                             ,              start by flattening the matrix of arguments                               ⌈/                reduce by max (find the highest number)
                                           compose both of these together
                        1+                  increment by one
 {         ⍵⊥⍺         }        convert inputs to the current base
 {       e            }        store the converted values in 3
 {      2             }        take the first 2 values
 {    ×/               }        multiply them together (reduce-multiply)
 {  e=                 }        compare with e (the converted inputs)
 {3                   }        only keep the result of the comparison with the 3rd element (expected result)
 {             :⍵      }        if truthy, return the current base.
 {                    }        otherwise...
 {                ⍺∇⍵+1}        ...recurse with the base incremented

Мы используем вспомогательную функцию, Inчтобы получить ввод в более приемлемом формате. В противном случае на вход поступает матрица из 3 столбцов.

'3 9 42' даст, например (читать сверху вниз, затем слева направо):

0 0 4
3 9 2

И для 'aA bB 36jk'(то же самое здесь. a10, b11, A36 и т. Д.)

 0  0  3
 0  0  6
10 11 19
36 37 20
Вен
источник
2

Питон 2 - 197 213

Какой монстр ... (по сравнению с CJam)

from string import*
I=raw_input()
x,y,z=I.split()
B=lambda s,b:sum(b**i*(digits+lowercase+uppercase).find(s[-i-1])for i in range(len(s)))
print([b for b in range(B(max(I),10)+1,62)if B(x,b)*B(y,b)==B(z,b)]+[0])[0]

К сожалению int, базовое преобразование может обрабатывать только базы до 36. Поэтому мне нужно было реализовать это самостоятельно. (Смотрите это замечательное решение .)

Фалько
источник
Убедитесь, что это не возвращает основание, меньшее или равное самым большим цифрам?
Мартин Эндер
@ MartinBüttner: я не уверен. По крайней мере, явно. У вас есть тестовый случай, когда это проблема? (На самом деле, генератором тестовых случаев должен заниматься OP ...)
Falko
Попробуйте 2 * 3 = 20, который имеет базу 3 в случае ошибки. 3 не является цифрой в троичной системе счисления.
Кей
2

CJam, 53 байта

lA,s'{,97>+'[,65>+f#_$W=1e>)63,>_@Wa/W%f{fb~*=}1#\0+=

Принимает три входа от STDIN как

6 9 42

Печатает, 0если продукт в любой базе не представляется возможным

Постараюсь в гольф это дальше.

Попробуй здесь

оптимизатор
источник
1

JavaScript (E6) 129 139

Рекурсивно попробуйте все базы от 2 до 62, возвращая -1, если никакое значение не в порядке.
Функция JavaScript parseInt работает с базой до 36, поэтому для больших баз требуется небольшая помощь.
Осторожно, параметры x, y, z являются строками, а не числами.
Это сложнее, чем кажется. Спасибо Мартину за то, что он указал на основную ошибку в первой версии.

F=(x,y,z,b=2,N=n=>[for(d of(t=0,n))t=(v=parseInt(d,36)+(d>'@'&d<'a')*26)<b?t*b+v:NaN]&&t)=>b<63?N(x)*N(y)!=N(z)?F(x,y,z,b+1):b:-1

Меньше гольфа

F=(x,y,z,b=2,
   D=d=>parseInt(d,36)+(d>'@'&d<'a')*26, // parse a single digit
   N=n=>[for(d of(t=0,n))t=(v=D(d))<b?t*b+v:NaN]&&t // parse a string
)=>b<63?N(x)*N(y)!=N(z)?F(x,y,z,b+1):b:-1

Проверьте в консоли FireFox / FireBug.
Тест пробует 1000 номеров с разными базами (до 36, а не 62). Стоит отметить, что найденная база может быть правильной, но меньше, чем база, сгенерировавшая тестовый пример.

for(i=0;i<1000;i++)
{
   x=Math.random()*100|0,y=Math.random()*100|0,z=x*y,b=Math.random()*35+2|0
   bx=x.toString(b),by=y.toString(b),bz=z.toString(b),
   nb=F(bx,by,bz)
   nx=parseInt(bx,nb),ny=parseInt(by,nb),nz=parseInt(bz,nb)
   // if (nx*ny != nz) // uncomment to se output for errors only
     console.log(x,y,z,'base '+b,bx,by,bz, 'found base '+nb,nx,ny,nz,nx*ny)
}
edc65
источник
@ MartinBüttner параметры - это строки (возможные значения - что-то вроде aA bB 36jk ...). Уточнил в ответе.
edc65
Ах да, это имеет смысл.
Мартин Эндер
1

Древесный уголь , 28 байт

I⌊Φ…⊕⍘⌈⁺⁺θηζ⁶²¦⁶³⁼×⍘θι⍘ηι⍘ζι

Попробуйте онлайн! Ссылка на подробную версию кода. Выходы, Noneесли не найдена действительная база. Объяснение:

         θ                      First input
        ⁺                       Concatenated with
          η                     Second input
       ⁺                        Concatenated with
           ζ                    Third input
      ⌈                         Maximum character (by ordinal)
     ⍘                          Converted from base
            ⁶²                  Literal 62
    ⊕                           Incremented
   …                            Range up to
               ⁶³               Literal 63
  Φ                             Filtered by
                    θ           First input
                   ⍘            Converted from base
                     ι          Current value
                  ×             Multiplied by
                       η        Second input
                      ⍘         Converted from base
                        ι       Current value
                 ⁼              Equals
                          ζ     Third input
                         ⍘      Converted from base
                           ι    Current value
 ⌊                              Minimum
I                               Cast to string
                                Implicitly print
Нил
источник
Возможно ли иметь программу TIO, которая использует фактический код, который вы опубликовали?
mbomb007
@ mbomb007 Вы можете попробовать это онлайн! но AST генератор кажется, думает , это Anyпо какой - то причине ...
Нил
0

Эрланг (escript) - 200

main(X)->m(2,X).
m(63,_)->0;m(C,X)->try[F,G,I]=[c(0,C,Y)||Y<-X],I=F*G,io:fwrite("~p",[C])catch _:_->m(C+1,X)end.
c(A,B,[H|T])->D=H-if$A>H->$0;$a>H->29;0<1->87end,if D<B->c(A*B+D,B,T)end;c(A,_,_)->A.

Добавьте два ведущих символа новой строки, которые должны присутствовать.

В читабельном:

#!/usr/bin/env escript

main(Args) -> test(2, Args).

test(63, _) -> 0;
test(Base, Args) ->
    try
        [Factor1, Factor2, Product] = [convert(0, Base, Arg) || Arg <- Args],
        Product = Factor1 * Factor2,
        io:fwrite("~p", [Base])
    catch _:_ ->
        test(Base + 1, Args)
    end.

convert(Accumulator, Base, [Head|Tail]) ->
    Digit = Head - if Head < $A -> $0;
                      Head < $a -> $A - 10 - 26;
                      true      -> $a - 10
                   end,
    if Digit < Base ->
        convert(Accumulator * Base + Digit, Base, Tail)
    end;
convert(Accumulator, _, _) -> Accumulator.

Призвание:

$ escript x.erl 6 9 42
13
$ escript -i x.erl a a 64
16
$ escript -i x.erl aA bB 36jk
41
$ escript -i x.erl 2 3 20
(no output)
$ escript -i x.erl 10 10 100
2
кай
источник
Убедитесь, что это не возвращает основание, меньшее или равное самым большим цифрам?
Мартин Эндер
Да, if Digit < Base -> … endчасть заботится об этом. Если ifблок не имеет истинной ветви, то генерируется исключение, которое попадает в try … catch _:_ -> … end.
Кей
0

Haskell 216 символов (177?)

Пытался играть в гольф как можно больше. Если считается импорт, то это мой самый короткий код (216)

import Data.Char
import Data.List
m=maximum
j[]=0;j(x:_)=x
f=reverse.map(\x->ord x-48)
g[]_=0;g(m:n)x=m+x*g n x
main=do
l<-getLine
let k@[x,y,z]=words l
print$j[n|n<-[2..62],g(f x)n*g(f y)n==g(f z)n,n>(m.map(m.f)$k)]

Однако если импорт не учитывался, то это моя лучшая версия (177):

import Data.Char
import Data.List
import Control.Applicative
m=maximum
j[]=0;j(x:_)=x
f=reverse.map(\x->ord x-48)
g[]_=0;g(m:n)x=m+x*g n x
main=words<$>getLine>>= \k@[x,y,z]->print$j[n|n<-[2..62],g(f x)n*g(f y)n==g(f z)n,n>(m.map(m.f)$k)]

Это рассматривает каждое число как полином P (x), где x - основание, при условии, что ни один коэффициент не больше x; Затем я оцениваю полиномы по каждому возможному основанию, останавливаясь, когда достигаю того, которое удовлетворяет равенству P (x) * Q (x) = R (x). Правило «база больше, чем самая большая цифра» применяется с последним охранником в сопоставлении с образцом, а именно n>(m.map(m.f)$k). Я знаю, что разные задачи в области гольфа и разные лица, принимающие участие в конкурсе, имеют разную политику в отношении импорта по отношению к подсчетам очков, поэтому возьмите вторую с долей соли.

archaephyrryx
источник
Решения на самом деле 216 и 177 байтов / символов, соответственно. Но второе решение является недействительным, поскольку импорт будут подсчитаны , если ОП явно не указано иное, что не тот случай, насколько я могу судить.
nyuszika7h
0

Пролог - 195 байт

В основном та же идея, что и мой ответ на Erlang:

:-use_module(library(main)).
main(A):-between(2,62,B),maplist(x(B),A,[F,G,P]),0is F*G-P,write(B).
c(I,B,Q,O):-Q=[H|T]->(H<65->D=48;H<97->D=29;D=87),H-D<B,c(I*B+H-D,B,T,O);O=I.
c(B)-->name,c(0,B).

В читабельном:

:- use_module(library(main)).

main(Args) :-
    between(2, 62, Base),
    maplist(convert(Base), Args, [Factor1, Factor2, Product]),
    0 is Factor1 * Factor2 - Product,
    write(Base).

convert(Accumulator, Base, List, Output) :-
    List = [Head|Tail] ->
        (   Head < 65 -> Offset = 48;
            Head < 97 -> Offset = 29;
                         Offset = 87),
        Head - Offset < Base,
        convert(Accumulator * Base + Head - Offset, Base, Tail, Output);
    Output = Accumulator.

convert(Base, Input, Output) :-
    name(Input, List),
    convert(0, Base, List, Output).

Призвание:

$ swipl -qg main x.pl 6 9 42
13
$ swipl -qg main x.pl aA bB 36jk
41
$ swipl -qg main x.pl 2 3 20
ERROR: Unknown message: goal_failed(main([2,3,20]))
кай
источник