Déterminer la base où une équation donnée est vraie

22

Étant donné 3 entiers, déterminez la base la plus basse possible pour que les deux premiers entiers se multiplient dans le troisième. Si vous pensez à la réponse à la question ultime de la vie, l'univers et tout, 6 * 9 == 42, est vrai dans la base 13.

Les entrées peuvent inclure tous les nombres dont les chiffres utilisent les caractères 0-9, az et AZ, où aest égal à 10 en Base 10 et Z61 en Base 10.

Les entrées doivent être entrées comme vous le souhaitez (sauf pour le codage en dur), et vous pouvez écrire soit une fonction individuelle, soit un programme entier.

La base maximale qui doit être prise en compte est la base 62 et la base minimale est la base 2.

Vous pouvez supposer que les deux premières valeurs sont inférieures à la troisième. Vous pouvez également conclure que la base minimale est supérieure au chiffre / caractère le plus élevé des entrées (par exemple, si les entrées le sont 3 1a 55, la base minimale serait Base 11, car il as'agit du chiffre le plus élevé).

S'il n'y a pas une telle base, renvoyez une valeur indésirable de votre choix.

C'est le golf de code, donc le code le plus court gagne.

Cas de test

6 9 42     -->   13
a a 64     -->   16
aA bB 36jk -->   41
2 3 20     -->   <junk value>
10 10 100  -->   2
erdekhayser
la source
Je pense que STDIN serait probablement mieux, et l'un ou l'autre irait bien.
erdekhayser
@ MartinBüttner Dois-je donc autoriser la saisie sous l'une ou l'autre forme?
erdekhayser
1
Pour clarifier ce qui devrait être fait si plusieurs bases sont valides, comme votre dernier exemple (qui a maintenant été supprimé - c'était 10 * 10 = 100), où il est également valide en base 10 et en fait dans toute autre base à laquelle vous vous souciez. mentionner ...
Chris
1
@Kay Si je définis le système positionnel dans la base bd'une manière générale comme a_0 b^0 + a_1 b^1 + a_2 b^2 + ...(où a_0est le chiffre le moins significatif) que la base 1 a vraiment du sens. De plus, la conclusion du PO inclurait également la base 1 dans la recherche si le plus grand chiffre actuel est 0.
Martin Ender
2
À propos de la base 1, unary est un système numérique. en.m.wikipedia.org/wiki/Unary_numeral_system
erdekhayser

Réponses:

3

CJam, 52 51 48 octets

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

Testez-le ici. Le testeur en ligne ne prend pas en charge la saisie via ARGV. L'alternative la plus proche est de mettre les entrées comme 6 9 42dans STDIN et d'utiliser:

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

Ceci s'imprime -1si aucune base valide jusqu'à 62 ne peut être trouvée.

Un grand merci à Peter pour le code d'analyse des chiffres!

J'ai corrigé de nombreux problèmes qui ajoutaient 14 octets au décompte. L'explication suivante concerne toujours ma soumission d'origine, et je la mettrai à jour demain.

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

L'index est imprimé automatiquement à la fin du programme.

Martin Ender
la source
Dans GS, les chiffres peuvent être analysés comme 32base~\[-16.35 9]=+. Je sais que CJam a une conversion de base plus courte.
Peter Taylor
7

APL (Dyalog Unicode) , 30 octets SBCS

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

Essayez-le en ligne!

Merci à Adám pour l'aide.

Explication:

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

Nous utilisons une fonction d'assistance,, Inpour recevoir l'entrée dans un format plus agréable au goût. Sinon, l'entrée reçoit une matrice de 3 colonnes.

'3 9 42' donnerait, par exemple (lire de haut en bas puis de gauche à droite):

0 0 4
3 9 2

Et pour 'aA bB 36jk'(même ici. aEst 10, best 11, Aest 36, etc.)

 0  0  3
 0  0  6
10 11 19
36 37 20
Ven
la source
2

Python 2-197 213

Quel monstre ... (par rapport à 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]

Malheureusement, intla conversion de base ne peut gérer que des bases jusqu'à 36. J'ai donc dû l'implémenter moi-même. (Voir cette merveilleuse solution .)

Falko
la source
Cela garantit-il de ne pas renvoyer une base inférieure ou égale aux plus gros chiffres?
Martin Ender
@ MartinBüttner: Je ne suis pas sûr. Du moins pas explicitement. Avez-vous un cas de test où c'est un problème? (En fait, la génération des cas de test devrait être prise en charge par l'OP ...)
Falko
Essayez 2 * 3 = 20 qui a la base 3 dans un cas d'erreur. 3 n'est pas un chiffre dans un système numérique ternaire.
kay
2

CJam, 53 octets

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

Prend les trois entrées de STDIN comme

6 9 42

Imprime 0si le produit dans n'importe quelle base n'est pas possible

Je vais essayer de jouer au golf plus loin.

Essayez-le ici

Optimiseur
la source
1

JavaScript (E6) 129 139

Essayez récursivement toutes les bases de 2 à 62, en retournant -1 si aucune valeur n'est correcte.
La fonction JavaScript parseInt fonctionne avec une base jusqu'à 36, donc un peu d'aide est nécessaire pour de plus grandes bases.
Attention, les paramètres x, y, z sont des chaînes, pas des nombres.
C'est plus difficile qu'il n'y paraît. Merci à Martin d'avoir signalé un bug de base dans la première version.

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

Moins golfé

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

Testez dans la console FireFox / FireBug.
Le test essaie 1000 numéros avec différentes bases (jusqu'à 36, pas 62). Il convient de noter que la base trouvée peut être correcte mais inférieure à la base qui a généré le scénario de test.

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
la source
@ MartinBüttner les paramètres sont des chaînes (car les valeurs possibles sont quelque chose comme aA bB 36jk ...). Clarifié dans la réponse.
edc65
Oh oui, cela a du sens.
Martin Ender
1

Fusain , 28 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Affiche Nonesi aucune base valide ne peut être trouvée. Explication:

         θ                      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
Neil
la source
Est-il possible d'avoir un programme TIO qui utilise le code réel que vous avez publié?
mbomb007
@ mbomb007 Vous pouvez l' essayer en ligne! mais le générateur AST semble penser que c'est Anypour une raison quelconque ...
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.

Ajoutez deux nouvelles lignes principales qui doivent être présentes.

En lecture:

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

Invocation:

$ 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
kay
la source
Cela garantit-il de ne pas renvoyer une base inférieure ou égale aux plus gros chiffres?
Martin Ender
Oui, la if Digit < Base -> … endpartie s'en occupe. Si un ifbloc n'a pas de véritable branche, alors une exception est levée, qui se retrouve coincée try … catch _:_ -> … end.
kay
0

Haskell 216 car (177?)

J'ai essayé de jouer au golf autant que possible. Si les importations sont comptées, alors c'est mon code le plus court (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)]

Cependant, si les importations n'étaient pas comptabilisées, voici ma meilleure version (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)]

Ceci traite chaque nombre comme un polynôme P (x) où x est la base, à condition qu'aucun coefficient ne soit supérieur à x; J'évalue ensuite les polynômes sur chaque base possible, en m'arrêtant lorsque j'atteins celui qui satisfait à l'égalité P (x) * Q (x) = R (x). La règle «la base est plus grande que le plus grand chiffre» est appliquée avec le dernier garde dans la correspondance de modèle, à savoir n>(m.map(m.f)$k). Je sais que différents défis de golf et différents fabricants de défis ont des politiques différentes concernant les importations vis-à-vis de la notation, alors prenez le deuxième avec un grain de sel.

archaephyrryx
la source
Les solutions sont respectivement de 216 et 177 octets / caractères. Mais la deuxième solution n'est pas valable, car les importations sont comptées, sauf indication contraire explicite de l'OP, ce qui n'est pas le cas ici pour autant que je sache.
nyuszika7h
0

Prolog - 195 octets

Fondamentalement, la même idée que ma réponse 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).

En lecture:

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

Invocation:

$ 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]))
kay
la source