Carrés magiques de chiffres romains ambigus

10

Le roi de la Rome antique a du mal à déterminer si un carré magique est valide ou non, car le carré magique qu'il vérifie ne comprend aucun séparateur entre les nombres. Il a engagé un ingénieur logiciel pour l'aider à déterminer si un carré magique est valide ou non.

Description de l'entrée

L'entrée vient sur les arguments STDIN ou de ligne de commande. Vous ne pouvez pas avoir l'entrée pré-initialisée dans une variable (par exemple "ce programme attend l'entrée dans une variable x"). L'entrée est au format suivant:

<top>,<middle>,<bottom>

Chacun de <top>, <middle>et <bottom>est une chaîne qui contiendra seulement jamais les caractères majuscules I, Vet X. Il ne contiendra aucun espace ni aucun autre caractère. Chaque chaîne représente trois chiffres romains, résultant ainsi en une matrice de nombres 3x3. Cependant, ces chiffres romains peuvent (mais pas nécessairement) être ambigus . Permettez-moi d'illustrer cela avec un exemple. Prenons l'exemple de la ligne suivante de trois chiffres romains, sans espace entre chaque numéro:

IVIIIIX

Parce qu'il n'y a pas d'espaces entre les lettres, il y a deux possibilités pour les nombres ici:

  • 1, 8, 9 ( I VIII IX)
  • 4, 3, 9 ( IV III IX)

Lorsque vous considérez que les trois lignes de la matrice peuvent être ambigües, il existe un potentiel pour qu'il existe de nombreuses matrices 3x3 différentes à partir d'une seule entrée.

Notez que les séquences telles que 1, 7, 1, 9 ( I VII I IX) ne sont pas possibles car chaque ligne représentera toujours trois chiffres romains. Notez également que les chiffres romains doivent être valides, donc des séquences telles que 1, 7, 8 (I VII IIX ) ne sont également pas possibles.

Description de sortie

Production:

  • Un entier A, où Aest le nombre de matrices 3x3 uniques qui peuvent être formées à partir de l'entrée ambigüe, et:
  • Une valeur vraie si l' une des matrices 3x3 uniques forme un carré magique, ou:
  • Une valeur fausse si aucune des matrices 3x3 uniques ne forme un carré magique.

Les valeurs véridiques et fausses doivent être cohérentes. Ils sont séparés par une virgule.

Une explication est requise sur ce qui est considéré comme unique. Tant qu'une matrice n'a pas exactement les mêmes nombres exactement aux mêmes positions qu'une matrice trouvée précédemment, elle est considérée comme unique. Cela signifie que les réflexions, etc. des matrices trouvées précédemment sont considérées comme uniques.

Exemples d'entrées et de sorties

Dans ces exemples, j'utilise truecomme valeur vraie et falsecomme valeur fausse.

Entrée: VIIIIVI,IIIVVII,IVIXII Sortie: 24,true (Le triangle magique est 8-1-6, 3-5-7, 4-9-2.)

Entrée: IIIXVIII,IVIII,VIIII Sortie:210,false

Suppléments

  • Vous n'êtes pas autorisé à utiliser des fonctions de conversion de chiffres romains intégrées si votre langue choisie en possède une.
Absinthe
la source
"roi de la Rome antique" ... Empereur?
Digital Trauma
8
@DigitalTrauma Il se déroule dans un univers alternatif où la Rome antique avait un roi, des carrés magiques et des ingénieurs logiciels. Ou quelque chose comme ça ...
absinthe
En outre, vous devez utiliser un interpunct (·) au lieu d'une virgule ( en.wikipedia.org/wiki/Interpunct#Latin )
coredump
J'ai "24, vrai" pour le premier, mais "210, faux" pour le deuxième exemple. Je vais enquêter.
coredump
1
@DigitalTrauma Rome avait des rois jusqu'à environ 509 avant JC.
Jon B

Réponses:

4

Perl, 219 237

Sauts de ligne ajoutés pour plus de clarté.

#!perl -p
%x=(I,1,IV,4,V,5,IX,9,X,10);
$a="(X{0,3}(?:V?I{1,3}|I?V|IX)|X{1,3})"x3;
m*^$a,$a,$a$(?{
  @z=map"$$_",0..9;
  $r|=!grep$x-$_,map{$x=eval s/./ $z[$&]/gr=~s/IX|IV|\S/+$x{$&}/gr}123,456,789,147,258,369,159,357;
  ++$-
})^*;
$_="$-,$r"

Testez- moi .

nutki
la source
4

Prolog - 686

:-lib(util),lib(sd). r(S,R):-string_list(S,L),g(L,R). g(L,[N1,N2,N3]):-append(L1,X,L),append(L2,L3,X),n(L1,N1),n(L2,N2),n(L3,N3). n([73,86],4). n([73,88],9). n([73,73,73],3). n([73,73],2). n([73],1). n([86],5). n([86|N],D):-n(N,E),E<4,D is E+5. n([88|N],D):-n(N,E),D is E+10. n([88],10). m(M,[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3]):-split_string(M,",","",[X,Y,Z]),r(X,[X1,X2,X3]),r(Y,[Y1,Y2,Y3]),r(Z,[Z1,Z2,Z3]). a(L):-alldifferent(L),L=[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3],l(X1,X2,X3,T),l(Y1,Y2,Y3,T),l(Z1,Z2,Z3,T),l(X1,Y1,Z1,T),l(X2,Y2,Z2,T),l(X3,Y3,Z3,T). l(A,B,C,T):-T is A+B+C. p:-read_line(S),findall(L,m(S,L),A),length(A,C),findall(L,(member(L,A),a(L)),B),(B=[_|_]->R=true;R=false),writeln((C,R)).

Non golfé

% I : 73
% V : 86
% X : 88
:-lib(util).
:-lib(sd).
r(S,R) :- string_list(S,L), g(L,R).
g(L,[N1,N2,N3]):-
    append(L1,X,L),
    append(L2,L3,X),
    n(L1,N1),n(L2,N2),n(L3,N3).
n([73,86],4).
n([73,88],9).
n([73,73,73],3).
n([73,73],2).
n([73],1).
n([86],5).
n([86|N],D):-n(N,E),E<4,D is E+5.
n([88|N],D):-n(N,E), D is E+10.
n([88],10).
m(M,[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3]) :-
    split_string(M,",","",[X,Y,Z]),
    r(X,[X1,X2,X3]),
    r(Y,[Y1,Y2,Y3]),
    r(Z,[Z1,Z2,Z3]).
a(L) :-
    alldifferent(L),
    L=[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3],
    l(X1,X2,X3,T),
    l(Y1,Y2,Y3,T),
    l(Z1,Z2,Z3,T),
    l(X1,Y1,Z1,T),
    l(X2,Y2,Z2,T),
    l(X3,Y3,Z3,T).
l(A,B,C,T):-T is A+B+C.
p :- read_line(S),
     findall(L,m(S,L),A),
     length(A,C),
     findall(L,(member(L,A),a(L)),B),
     (B=[_|_]->R=true;R=false),
     writeln((C,R)).

Bien sûr, ppourrait également être défini comme:

p :- read_line(S),
     findall(L,m(S,L),A),
     length(A,C),
     findall(L,(member(L,A),a(L)),B),
     writeln(C),
     B=[_|_].

Dans ce cas, l'environnement dirait «Oui» ou «Non» après avoir écrit le nombre de carrés.

Exemple

Utilisation d' éclipse .

[eclipse 105]: p.
 VIIIIVI,IIIVVII,IVIXII
24, true

[eclipse 106]: p.
 IIIXVIII,IVIII,VIIII
210, false

Des exemples de résultats pour le second sont collés ici .

coredump
la source
2

Python, 442 caractères

R=range
L=len
S=sum
N={}
for i in R(40):
 r="";j=i
 while j>9:r+="X";j-=10
 if j>8:r+="IX";j-=9
 if j>4:r+="V";j-=5
 if j>3:r+="IV";j-=4
 N[r+"III"[:j]]=i
a,b,c=map(lambda x:sum([[Z]*all(Z)for i in R(L(x))for j in R(L(x))for Z in[map(N.get,(x[:i],x[i:j],x[j:]))]],[]),raw_input().split(","))
print L(a)*L(b)*L(c),any(S(x)==S(y)==S(z)==S(q[::3])==S(q[1::3])==S(q[2::3])==S(q[::4])==S(q[2:-1:2])for x in a for y in b for z in c for q in[x+y+z])

Le code construit d'abord Nqui est un mappage de la chaîne de chiffres romains à sa valeur pour tous les nombres possibles dont nous pourrions avoir besoin. Divise chaque ligne en trois de toutes les manières possibles et vérifie dans lequel des triplets résultants tous ont des correspondances N. La finale anyvoit si une combinaison est un carré magique.

Keith Randall
la source
2

Haskell, 451 429 423 octets

import Data.List
(#)=splitAt
(%)=map
w=length
r"X"=10
r('X':a)=10+r a
r a=case elemIndex a["I","II","III","IV","V","VI","VII","VIII","IX"]of Just i->i+1;_->0
s l=[r%[a,b,c]|x<-[2..w l],y<-[1..x],let(d,c)=x#l;(a,b)=y#d,r a*r b*r c>0]
e[a,b,c]=a==b&&a==c
p[l,m,n]=[1|a<-l,b<-m,c<-n,e$sum%[a,b,c],e$sum%(transpose[a,b,c])]
f i=(show$product$w%(s%i))++","++(show$0<(w$p$s%i))
q ','='\n'
q a=a
i=getLine>>=putStrLn.f.lines.map q

Usage:

*Main> i                           -- repl prompt, call i
VIIIIVI,IIIVVII,IVIXII             -- input via STDIN    
24,True                            -- output
*Main> i
IIIXVIII,IVIII,VIIII
210,False

Environ 70 octets juste pour obtenir le bon format d'entrée et de sortie.

La fonction rconvertit un nombre romain (donné sous forme de chaîne) en un entier (si ce n'est pas un nombre romain valide qui 0est retourné). sdivise une chaîne de chiffres romains en 3 sous-chaînes et conserve ces triplets avec des nombres romains valides et les convertit via ren entiers. evérifie si tous les entiers d'une liste de trois éléments sont égaux. pprend trois chaînes de chiffres romains, les divise via sen listes d'entiers, combine un entier de chaque liste en triplets et conserve ceux avec des sommes égales dans toutes les directions. fcalcule le nombre de matrices valides et vérifie si prenvoie la liste vide (pas de solution valide) ou non (il existe une solution valide). La fonction principale ilit l'entrée de STDIN, la convertit en une liste de chaînes (qaide en remplaçant ,par \n) et les appels p.

nimi
la source
1

R, 489 474 464

Cela est devenu beaucoup plus gros que je ne le voulais, mais je pense que je peux le jouer un peu.

Il utilise une méthode de force brute, en calculant toutes les combinaisons possibles de chiffres romains et leurs chiffres correspondants.

Une fois cela fait, il compare l'entrée à la liste des chiffres romains et obtient les chiffres possibles.

De là, il parcourt chaque matrice de nombres et teste le carré magique, pour finalement produire le résultat.

s=strsplit;e=expand.grid;P=paste0;d=do.call;i=readline();i=s(i,',');n=1:39;r=c(t(outer(c('','X','XX','XXX'),c('I','II','III','IV','V','VI','VII','VIII','IX','X'),P)))[n];p=d(P,e(r,r,r));n=d(paste,e(n,n,n));m=lapply(i[[1]],function(x)which(p==x));C=e(s(n[m[[1]]],' '),s(n[m[[2]]],' '),s(n[m[[3]]],' '));E=F;N=nrow(C);for(n in 1:N){T=matrix(strtoi(unlist(C[n,])),nr=3);E=E||length(unique(c(rowSums(T),colSums(T),sum(diag(T)),sum(diag(T[3:1,])))))==1};P(N,',',any(E))

Essai. Il attend l'entrée une fois collé dans le RGui.

> e=expand.grid;l=length;s=strsplit;P=paste0;i=readline();i=s(i,',');n=1:39;r=c(t(outer(c('','X','XX','XXX'),c('I','II','III','IV','V','VI','VII','VIII','IX','X'),P)))[-40];p=do.call(P,e(r,r,r));n=do.call(paste,e(n,n,n));m=lapply(i[[1]],function(x)which(p==x));C=e(s(n[m[[1]]],' '),s(n[m[[2]]],' '),s(n[m[[3]]],' '));E=c();N=nrow(C);for(n in 1:N){T=matrix(as.integer(unlist(C[n,])),nr=3);E=c(E,length(unique(c(rowSums(T),colSums(T),sum(diag(T)),sum(diag(T[3:1,])))))==1)};paste(N,',',any(E))
VIIIIVI,IIIVVII,IVIXII
[1] "24 , TRUE"
> e=expand.grid;l=length;s=strsplit;P=paste0;i=readline();i=s(i,',');n=1:39;r=c(t(outer(c('','X','XX','XXX'),c('I','II','III','IV','V','VI','VII','VIII','IX','X'),P)))[-40];p=do.call(P,e(r,r,r));n=do.call(paste,e(n,n,n));m=lapply(i[[1]],function(x)which(p==x));C=e(s(n[m[[1]]],' '),s(n[m[[2]]],' '),s(n[m[[3]]],' '));E=c();N=nrow(C);for(n in 1:N){T=matrix(as.integer(unlist(C[n,])),nr=3);E=c(E,length(unique(c(rowSums(T),colSums(T),sum(diag(T)),sum(diag(T[3:1,])))))==1)};paste(N,',',any(E))
IIIXVIII,IVIII,VIIII
[1] "210 , FALSE"
>
MickyT
la source