Визначте основу, де задане рівняння є істинним


22

Дано 3 цілих числа, визначте найнижчу можливу основу, щоб перші два цілі числа помножилися на треті. Якщо ви думаєте, що відповідь на остаточне питання життя, Всесвіту і всього, 6 * 9 == 42, вірно в Базі 13.

Вхідні дані можуть включати будь-які числа, в цифрах яких використовуються символи 0-9, az та AZ, де aдорівнює 10 у базі 10, таZ в базі 10 - 61.

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

Максимальна база, яку необхідно враховувати, - це база 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

Я думаю, що STDIN, мабуть, буде кращим, і будь-який буде добре.
erdekhayser

@ MartinBüttner Отже, я повинен просто дозволити введення в будь-якій формі?
erdekhayser

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
erdekhayser

Відповіді:


3

CJam, 52 51 48 байт

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

Перевірте це тут. Онлайн-тестер не підтримує введення даних через ARGV. Найближча альтернатива полягає в тому, щоб поставити вхід типу 6 9 42STDIN і використовувати:

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, bце 11, Aє 36 і т.д.)

 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: Я не впевнений. Принаймні, не прямо. Чи є у вас тестовий випадок, коли це питання? (Насправді, про створення тестових справ слід опікуватися ОП ...)
Фалько,

Спробуйте 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)
}

@ 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

Ерланг (ескрипт) - 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 char (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). Я знаю, що різні виклики в гольфі та різні ті, хто займається проблемами, мають різну політику щодо імпорту по відношенню до скорингу, тому візьміть другу із зерном солі.


Рішень насправді 216 та 177 байт / символів відповідно. Але друге рішення є недійсним, оскільки імпорт будуть підраховані , якщо ОП явно не вказано інше, що не той випадок, наскільки я можу судити.
nyuszika7h

0

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

В основному та сама ідея, що і моя відповідь Ерланга:

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