Двусмысленные римские цифры магических квадратов

10

Королю Древнего Рима трудно определить, действителен ли магический квадрат или нет, потому что проверяемый им магический квадрат не содержит разделителей между числами. Он нанял разработчика программного обеспечения, чтобы помочь ему определить, действителен ли магический квадрат или нет.

Описание входа

Входные данные поступают в STDIN или аргументы командной строки. Вы не можете предварительно инициализировать ввод в переменной (например, «эта программа ожидает ввод в переменной x»). Ввод в следующем формате:

<top>,<middle>,<bottom>

Каждый из <top>, <middle>и <bottom>это строка , которая будет всегда содержать только символы в верхнем регистре I, Vи X. Он не будет содержать пробелов или любых других символов. Каждая строка представляет три римские цифры, в результате чего получается матрица чисел 3х3. Однако эти римские цифры могут (но не обязательно) быть неоднозначными . Позвольте мне проиллюстрировать это на примере. Рассмотрим следующий пример строки из трех римских цифр без пробелов между каждым числом:

IVIIIIX

Поскольку между буквами нет пробелов, здесь есть две возможности для чисел:

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

Если учесть, что все три строки матрицы могут быть неоднозначными, существует вероятность, что с одного входа будет много разных матриц 3х3.

Обратите внимание, что такие последовательности, как 1, 7, 1, 9 ( I VII I IX) невозможны, поскольку каждая строка всегда будет представлять три римские цифры. Также обратите внимание, что римские цифры должны быть действительными, поэтому такие последовательности, как 1, 7, 8 ( I VII IIX) также невозможны.

Описание выхода

Вывод:

  • Целое число A, где A- количество уникальных матриц 3х3, которые можно сформировать из неоднозначного ввода, и:
  • Truthy значение , если какой - либо из уникальных 3x3 матриц образуют магический квадрат, или:
  • Falsy значение , если ни один из уникальных 3x3 матриц не образуют магический квадрат.

Истинные и ложные ценности должны быть последовательными. Они разделены запятой.

Требуется некоторое объяснение того, что считается уникальным. Пока матрица не имеет точно такие же числа в тех же позициях, что и ранее найденная матрица, она считается уникальной. Это означает, что отражения и т. Д. Ранее найденных матриц считаются уникальными.

Пример входов и выходов

В этих примерах я использую trueсвою истинную ценность и falseсвою ложную ценность.

Вход: VIIIIVI,IIIVVII,IVIXII Выход: 24,true (Волшебный треугольник 8-1-6, 3-5-7, 4-9-2.)

Вход: IIIXVIII,IVIII,VIIII Выход:210,false

Дополнительно

  • Вам не разрешается использовать встроенные функции преобразования римских цифр, если у выбранного вами языка есть такие.
абсент
источник
"король Древнего Рима" ... Император?
Цифровая травма
8
@DigitalTrauma Он расположен в альтернативной вселенной, где в Древнем Риме были король, магические квадраты и разработчики программного обеспечения. Или что-то в этом роде ...
Абсент
Кроме того, вы должны использовать interpunct (·) вместо запятой ( en.wikipedia.org/wiki/Interpunct#Latin )
coredump
У меня «24, правда» для первого, но «210, ложь» для второго примера. Я буду расследовать.
coredump
1
@DigitalTrauma Рим имел королей примерно до 509 г. до н.э.
Джон Б

Ответы:

4

Perl, 219 237

Добавлены разрывы строк для ясности.

#!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"

Проверь меня .

nutki
источник
4

Пролог - 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)).

Ungolfed

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

Конечно, pтакже может быть определено как:

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

В этом случае окружение скажет «Да» или «Нет» после записи количества квадратов.

пример

Используя затмение .

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

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

Результаты примера для второго вставлены здесь .

CoreDump
источник
2

Python, 442 символа

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])

Сначала строится код, Nкоторый представляет собой отображение строки римских цифр на ее значение для всех возможных чисел, которые нам могут понадобиться. Разбивает каждую строку на три всеми возможными способами и проверяет, какие из получающихся троек имеют все отображения N. Финал anyвидит, является ли любая комбинация магическим квадратом.

Кит Рэндалл
источник
2

Haskell, 451 429 423 байта

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

Применение:

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

Около 70 байтов только для правильного формата ввода и вывода.

Функция rпреобразует римское число (заданное в виде строки) в целое число (если оно не верное, 0возвращается римское число ). sразбивает строку римских цифр на 3 подстроки и сохраняет эти тройки с действительными римскими числами и преобразует их rв целые числа. eпроверяет, равны ли все целые числа трехэлементного списка. pберет три строки римских цифр, разбивает их sна списки целых чисел, объединяет одно целое число каждого списка в тройки и сохраняет одинаковые суммы во всех направлениях. fвычисляет количество допустимых матриц и проверяет, лиp возвращает ли пустой список (нет правильного решения) или нет (существует правильное решение). Основная функция iчитает входные данные из STDIN, преобразует их в список строк (qпомогает путем замены ,на \n) и звонки p.

Ними
источник
1

R 489 474 464

Это стало намного больше, чем я хотел, но я подозреваю, что могу немного проиграть.

Он использует метод грубой силы, вычисляя все возможные комбинации римских цифр и соответствующие им цифры.

Как только это будет сделано, он сравнивает входные данные со списком римских цифр и получает возможные цифры.

Оттуда он проходит каждую матрицу чисел и проверяет магический квадрат, наконец выводя результат.

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

Тестовый забег. Он ожидает ввода после вставки в 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
источник