You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.4 KiB
109 lines
2.4 KiB
:- use_module(library(clpfd)).
|
|
|
|
% den state kannst du mit nem dictoniary modellieren:
|
|
initState(state{ x: 0, y: 0, z:0, w: 0 , in: I}, I).
|
|
% Dictonary lookup: initstate(State), R = State.x
|
|
% Dictonary update: initstate(State), NewState = State.put(x, 1)
|
|
|
|
% Convert List of input digits into single number
|
|
%input_number(+Inputs, -Number)
|
|
input_number(Inputs, Number) :- atomic_list_concat(Inputs, Number).
|
|
|
|
|
|
% read program helper functions
|
|
noteof(L) :- \+ L = [end_of_file].
|
|
string_term(String,Term) :- term_string(Term, String).
|
|
parse_instr(String, Inst) :-
|
|
split_string(String, " ", "", Words),
|
|
maplist(string_term, Words, Inst).
|
|
|
|
% Read a list of Instructions from Filename
|
|
% read_program(+Filename, -Prog)
|
|
read_program(Filename, Prog) :-
|
|
open(Filename, read, Str),
|
|
read_string(Str, _, S),
|
|
split_string(S, "\n", "", Lines),
|
|
maplist(parse_instr, Lines, Instrs),
|
|
include(noteof, Instrs, Prog),
|
|
close(Str).
|
|
|
|
% Takes input and state and binds O to a number
|
|
num(N,S,O) :-
|
|
atom(N),
|
|
O = S.N.
|
|
|
|
num(N,S,O) :-
|
|
number(N),
|
|
O = N.
|
|
|
|
eq(A,B,R) :-
|
|
A = B,
|
|
R = 1.
|
|
|
|
eq(A,B,R) :-
|
|
A #\= B,
|
|
R = 0.
|
|
|
|
read_input(In,F,NIn) :-
|
|
[F | NIn] = In.
|
|
|
|
% interprets an instruction
|
|
% interpret(+list,+state,R)
|
|
interpret([inp, A],InState,OutState) :-
|
|
read_input(InState.in,C,NInput),
|
|
BS = InState.put(A,C),
|
|
OutState = BS.put(in,NInput).
|
|
|
|
interpret([add, A, B],InState,OutState) :-
|
|
num(B,InState,C),
|
|
R #= InState.A + C,
|
|
OutState = InState.put(A,R).
|
|
|
|
interpret([mul, A, B],InState,OutState) :-
|
|
num(B,InState,C),
|
|
R #= InState.A*C,
|
|
OutState = InState.put(A,R).
|
|
|
|
interpret([div, A, B],InState,OutState) :-
|
|
num(B,InState,C),
|
|
R #= InState.A div C,
|
|
OutState = InState.put(A,R).
|
|
|
|
interpret([mod, A, B],InState,OutState) :-
|
|
num(B,InState,C),
|
|
R #= InState.A mod C,
|
|
OutState = InState.put(A,R).
|
|
|
|
interpret([eql, A, B],InState,OutState) :-
|
|
num(B,InState,C),
|
|
eq(InState.A, C, R),
|
|
OutState = InState.put(A,R).
|
|
|
|
rprogram(State,[],O) :-
|
|
O = State.z.
|
|
|
|
rprogram(State,[I|Instr], O) :-
|
|
interpret(I,State,Out),
|
|
rprogram(Out,Instr,O).
|
|
|
|
program(Instr,Input) :-
|
|
length(Input, 14),
|
|
Input ins 1..9,
|
|
initState(S,Input),
|
|
rprogram(S,Instr, O),
|
|
O = 0.
|
|
|
|
max_monad(M) :-
|
|
read_program(input24,Instr),
|
|
program(Instr,R),
|
|
labeling([max,down],R),
|
|
input_number(R,M),
|
|
write(M).
|
|
|
|
min_monad(M) :-
|
|
read_program(input24,Instr),
|
|
program(Instr,R),
|
|
labeling([min],R),
|
|
input_number(R,M),
|
|
write(M).
|
|
|
|
|