Here is the Perl solution and output:
/* PROGRAM */
my @num = <>;
chomp $_ for @num; # remove newline from each number
@num = map { sprintf "'%s'", $_ } @num ;
my $paren = sprintf '(%s)', join ',', @num;
print $paren;
/* TRANSCRIPT */
[tbrannon@Ghostdc7600] [~/prg/prolog/comp.lang.prolog] perl makein.pl
050016411
050016412
050016409
050016410
050016407
050016408
050016405
050016406
('050016411','050016412','050016409','050016410','050016407','050016408','050016405','050016406','')
Its of course Perl's strength, but it isn't that bad in (SWI-)Prolog:
================================================================
#!/home/jan/bin/pl -q -g run,halt -s
run :-
read_numbers(List),
maplist(number_quoted_atom, List, Quoted),
atomic_list_concat(Quoted, ',', Atom),
format('(~w)~n', Atom).
number_quoted_atom(Number, Atom) :-
atomic_list_concat(['\'', Number, '\''], Atom).
read_numbers(List) :-
read_line_to_codes(current_input, Line),
read_numbers(Line, List).
read_numbers(end_of_file, []) :- !.
read_numbers(Line, [H|T]) :-
number_codes(H, Line),
read_line_to_codes(current_input, Line2),
read_numbers(Line2, T).
================================================================
./x
|: 050016411
|: 050016412
|: 050016409
|: 050016410
|: 050016407
|: 050016408
|: 050016405
|: 050016406
|: ('50016411','50016412','50016409','50016410','50016407','50016408','50016405','50016406')
For the portability note: atomic_list_concat is supported by a few Prolog's.
read_line_to_codes/2 is from the SWI-Prolog library. format/2 is supported by
many more and the rest is ISO (oh, that is only number_codes/2 :-()
Cheers --- Jan
Here is a shorter version in SICStus with logical loops:
main :-
read_line(Head),
atom_codes(A, Head),
read_line(Line),
( fromto(Line,L1,L2,end_of_file),
fromto(A,A1,A2,Last),
fromto(Term,(A1,T2),T2,Last)
do atom_codes(A2, L1),
read_line(L2)
),
format("(~q)\n", [Term]).
| ?- main.
|: 123
|: 234
|: 345
|: 456
|: 567
|: ('123','234','345','456','567')
yes
Cute, but you are cheating a little. You do not read numbers, but rely
on the fact that an atom containing digits gets quotes when written
using ~q ...
Cheers --- Jan
Since you give a pure input/output specification, you should receive
-ideally- also a pure solution in Prolog.
For the input part you can use library(pio) of SWI Prolog.
I.e, you can parse the file directly with a DCG. My favorite is
grep:
... --> [] | [_], ... . % That should be in a library
?- phrase_from_file(file, (...,"the search string",...)).
Now succeeds if file contains the search string.
That is not as comfortable as Perl, but I am quite
convinced that what is lacking here are just some nice libraries.
Feel free to consider some.
The output part will be covered by pio as well. But to make
it stable takes some time.
How about this one?
main :-
readLine(First),
loop('(',First,_).
loop(_,[],DoOut):-!,DoOut=go,writeln(')').
loop(Deli,Line,DoOut):-
freeze(DoOut,format("~w'~s'",[Deli,Line])), % don't do the output
until DoOut is nonvariable
readLine(NLine),
loop(',',NLine,DoOut).
Cheers,
Neng-Fa
Operations on input stream cause side effects, that is a general
concept accepted by functional programming language programmers. In
Prolog, backtracking would not work after reading an item from the
input stream. So I wrote my sequence reading program in the following
fashion.
read_sequence(Z) :-
read(X),
( X == end, Z = nil, !;
number_chars(X, X1), atoms_concat(X1, X2),
read_sequence(Y), ( Y == nil, Z = (X2), !;
Z = (X2, Y)
)
).
atoms_concat([], '').
atoms_concat([X|Y], Z) :-
atoms_concat(Y, Y1),
atom_concat(X, Y1, Z).
------------------------------
?- read_sequence(X).
| 050016411.
| 050016412.
| 050016409.
| 050016410.
| 050016407.
| 050016408.
| 050016405.
| 050016406.
| end.
X = ('50016411', '50016412', '50016409', '50016410', '50016407',
'50016408', '50016405', '50016406').
It seems fine. However, every item in input sequence was treated as a
number but an atom, and the leading zero of every item was eliminated.
How to correct it?