Określ podstawę, w której dane równanie jest prawdziwe


22

Biorąc pod uwagę 3 liczby całkowite, określ najniższą możliwą zasadę dla pierwszych dwóch liczb całkowitych pomnożonych przez trzecią. Jeśli pomyślisz o odpowiedzi na ostateczne pytanie życia, wszechświat i wszystko, 6 * 9 == 42, jest prawdziwe w bazie 13.

Dane wejściowe mogą zawierać dowolne liczby, których cyfry używają znaków 0–9, az i AZ, gdzie aw Bazie 10 jest równa 10, orazZ 61 w bazie 10.

Wejścia powinny być wprowadzane w dowolny sposób (z wyjątkiem kodowania na sztywno) i można napisać pojedynczą funkcję lub cały program.

Maksymalna baza, którą należy wziąć pod uwagę, to Baza 62, a minimalna baza to Baza 2.

Możesz założyć, że dwie pierwsze wartości są mniejsze niż trzecia. Można również stwierdzić, że minimalna podstawa jest o jeden większa niż najwyższa cyfra / znak z wejść (na przykład, jeśli dane wejściowe są 3 1a 55, minimalna podstawa to Podstawa 11, ponieważa jest to najwyższa cyfra).

Jeśli nie ma takiej podstawy, zwróć wybraną wartość śmieci.

To jest kod golfowy, więc wygrywa najkrótszy kod.

Przypadki testowe

6 9 42     -->   13
a a 64     -->   16
aA bB 36jk -->   41
2 3 20     -->   <junk value>
10 10 100  -->   2

Myślę, że STDIN byłby prawdopodobnie lepszy, i jedno z nich byłoby w porządku.
erdekhayser

@ MartinBüttner Czy powinienem pozwolić na wprowadzanie danych w dowolnej formie?
erdekhayser

1
W celu wyjaśnienia, co należy zrobić, jeśli wiele zasad jest poprawnych, takich jak twój ostatni przykład (który został teraz usunięty - było to 10 * 10 = 100), gdzie jest on również ważny w podstawie 10 i rzeczywiście w każdej innej bazie, na której ci zależy wspomnieć ...
Chris,

1
@Kay Jeśli zdefiniuję system pozycyjny w bazie bw ogólny sposób, jak a_0 b^0 + a_1 b^1 + a_2 b^2 + ...(gdzie a_0jest najmniej znacząca cyfra), to podstawa 1 na pewno ma sens. Ponadto wniosek PO obejmowałby również bazę 1 w wyszukiwaniu, jeśli największa obecna cyfra to 0.
Martin Ender

2
O bazie 1, unary to system liczbowy. en.m.wikipedia.org/wiki/Unary_numeral_system
erdekhayser

Odpowiedzi:


3

CJam, 52 51 48 bajtów

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

Sprawdź to tutaj. Tester online nie obsługuje wprowadzania danych przez ARGV. Najbliższą alternatywą jest umieszczenie wejścia jak 6 9 42w STDIN i użycie:

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

To drukuje -1 jeśli nie można znaleźć prawidłowej bazy do 62.

Bardzo dziękuję Peterowi za cyfrowy kod parsujący!

Naprawiłem wiele problemów, które dodawały 14 bajtów do liczby. Poniższe wyjaśnienie jest nadal związane z moim pierwotnym przesłaniem i zaktualizuję je jutro.

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.";

Indeks jest drukowany automatycznie na końcu programu.


W GS cyfry można parsować jako 32base~\[-16.35 9]=+. Wiem, że CJam ma krótszą konwersję bazy.
Peter Taylor

7

APL (Dyalog Unicode) , 30 bajtów SBCS

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

Wypróbuj online!

Dzięki Adámowi za pomoc.

Wyjaśnienie:

⊢{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

Używamy funkcji pomocnika In, aby otrzymać dane wejściowe w bardziej smacznym formacie. W przeciwnym razie dane wejściowe otrzyma macierz 3 kolumn.

'3 9 42' dałby na przykład (czytaj od góry do dołu, od lewej do prawej):

0 0 4
3 9 2

I dla 'aA bB 36jk'(to samo tutaj. aTo 10, bto 11, Ato 36 itp.)

 0  0  3
 0  0  6
10 11 19
36 37 20

2

Python 2 - 197 213

Co za potwór ... (w porównaniu do 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]

Niestety intkonwersja bazy może obsłużyć tylko bazy do 36. Musiałem więc zaimplementować ją samodzielnie. (Zobacz to wspaniałe rozwiązanie .)


Czy to gwarantuje, że nie zwróci bazy mniejszej lub równej największym cyfrom?
Martin Ender

@ MartinBüttner: Nie jestem pewien. Przynajmniej nie wprost. Czy masz przypadek testowy, w którym jest to problem? (Właściwie generowanie przypadków testowych powinno być załatwione przez PO ...)
Falko

Spróbuj 2 * 3 = 20, która ma podstawę 3 w przypadku błędu. 3 nie jest cyfrą w trójskładnikowym systemie liczbowym.
kay

2

CJam, 53 bajty

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

Pobiera trzy dane wejściowe ze STDIN jak

6 9 42

Wydruki 0 jeśli produkt w dowolnej bazie nie jest możliwy

Spróbuję dalej grać w golfa.

Wypróbuj tutaj


1

JavaScript (E6) 129 139

Rekurencyjnie wypróbuj wszystkie zasady od 2 do 62, zwracając -1, jeśli żadna wartość nie jest poprawna.
JavaScript parsowanie Funkcja działa z bazą do 36, więc potrzebna jest niewielka pomoc dla większych baz.
Uwaga, parametry x, y, z są ciągami, a nie liczbami.
To trudniejsze niż się wydaje. Podziękowania dla Martina za wskazanie podstawowego błędu w pierwszej wersji.

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

Mniej golfa

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

Testuj w konsoli FireFox / FireBug.
Test wypróbowuje 1000 liczb z różnymi zasadami (do 36, a nie 62). Warto zauważyć, że znaleziona baza może być poprawna, ale mniejsza niż baza, która wygenerowała przypadek testowy.

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 parametry są ciągami znaków (możliwe wartości to coś w rodzaju aA bB 36jk ...). Wyjaśnione w odpowiedzi.
edc65

No tak, to ma sens.
Martin Ender

1

Węgiel drzewny , 28 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyprowadza, Nonejeśli nie można znaleźć prawidłowej bazy. Wyjaśnienie:

         θ                      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

Czy to możliwe, aby mieć program TIO, który korzysta z faktycznie opublikowanego kodu?
mbomb007

@ mbomb007 Możesz wypróbować online! ale AST generator wydaje się myśleć, to Anyz jakiegoś powodu ...
Neil

0

Erlang (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.

Dodaj dwie nowe linie, które muszą być obecne.

W czytelnym:

#!/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.

Wezwanie:

$ 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

Czy to gwarantuje, że nie zwróci bazy mniejszej lub równej największym cyfrom?
Martin Ender

Tak, if Digit < Base -> … endczęść się tym zajmuje. Jeśli ifblok nie ma prawdziwej gałęzi, generowany jest wyjątek, który zostaje złapany try … catch _:_ -> … end.
kay

0

Haskell 216 char (177?)

Próbowałem zagrać w golfa tak bardzo, jak to możliwe. Jeśli importowane są, to jest to mój najkrótszy kod (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)]

Jednak jeśli import nie był liczony, to jest moja najlepsza wersja (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)]

To traktuje każdą liczbę jako wielomian P (x), gdzie x jest podstawą, pod warunkiem, że żaden współczynnik nie jest większy niż x; Następnie oceniam wielomiany na każdej możliwej podstawie, zatrzymując się, gdy osiągnę taką, która spełnia równość P (x) * Q (x) = R (x). Reguła „baza jest większa niż największa cyfra” jest egzekwowana z ostatnim strażnikiem w dopasowaniu wzorca, a mianowicie n>(m.map(m.f)$k). Wiem, że różne wyzwania golfowe i różni decydenci mają różne zasady dotyczące importu w stosunku do punktacji, więc weź drugie z odrobiną soli.


Rozwiązania mają w rzeczywistości odpowiednio 216 i 177 bajtów / znaków. Ale drugie rozwiązanie jest nieprawidłowe, ponieważ importy liczone, chyba że PO wyraźnie określi inaczej, co nie jest tutaj prawdą, o ile wiem.
nyuszika7h

0

Prolog - 195 bajtów

Zasadniczo ten sam pomysł, co moja odpowiedź Erlanga:

:-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).

W czytelnym:

:- 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).

Wezwanie:

$ 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]))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.