4
\$\begingroup\$

Your task is to write a program to perform set operations. The operations and arguments are taken from command line in the format program operation [argument]. There are four operations:

  1. 1: clears the set. no arguments. exit code 0.
  2. 2 integer: adds the integer into the set. exit code 0.
  3. 3 integer: removes the integer from the set. exit code 0.
  4. 4 integer: queries the set for integer. exit code 0 if integer exists or 1 otherwise.

The integer is a 64-bits integer. Shortest program wins. You can, of course, use a temporary file. However, watch out the space and time limit.

Example:

$ program 1 ; echo $?
0
$ program 2 10 ; echo $?
0
$ program 4 10 ; echo $?
0
$ program 3 10 ; echo $?
0
$ program 4 10 ; echo $?
1
$ program 2 10 ; echo $?
0
$ program 1 ; echo $?
0
$ program 4 10 ; echo $?
1
\$\endgroup\$
3
  • \$\begingroup\$ @Joey. Yes. That's why you should use a file. \$\endgroup\$
    – Alexandru
    Feb 26, 2011 at 0:11
  • \$\begingroup\$ Your 4th test assert an exit code of 1 which is not according to the specification (where 3 would always return 0). \$\endgroup\$
    – Joey
    Feb 26, 2011 at 16:30
  • \$\begingroup\$ @Joey: thank you. I missed that. \$\endgroup\$
    – Alexandru
    Feb 26, 2011 at 16:38

6 Answers 6

7
\$\begingroup\$

Bash -- 54 chars

case $1 in
1)rm *;w;;
2)>$2;;
3)rm $2;w;;
4)<$2;;
esac

Notes: Outputs to stdout/stderr in some scenarios. Empties working directory when clearing the set. Uses one file for each set element. The purpose of ;w is to exit with status 0.

This appears to comply with all the rules.

\$\endgroup\$
1
  • \$\begingroup\$ I find it brilliant that you use separate files for each argument. \$\endgroup\$
    – Eelvex
    Feb 26, 2011 at 8:32
2
\$\begingroup\$

bash, 74

case $1 in
1)>f;;
2)echo $2>>f;;
3)sed -i /^$2$/d f;;
4)grep ^$2$ f;;
esac

note I'm not plagiarizing Peter Taylor, it's just that it's not working with [ test ]s

\$\endgroup\$
2
\$\begingroup\$

Bash: 106 chars

touch f
case $1 in
1)rm -f f;;
2)echo $2>>f;;
3)grep -vx $2 f>g;mv g f;;
4)grep -x $2 f&>/dev/null;;
esac

Counting newlines as one character. Requires two temp files and POSIX grep. I'm unclear as to the precise constraints on temp files: if I can have two kicking around all the time then I can save 8 chars by writing to g rather than /dev/null in case 4.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ If you add number '123' and then query for '23' what's the exit code? \$\endgroup\$
    – Eelvex
    Feb 25, 2011 at 23:43
  • 1
    \$\begingroup\$ @Eelvex, good catch. I had -x on one grep but not on the other. \$\endgroup\$ Feb 26, 2011 at 7:08
2
\$\begingroup\$

Python - 167 chars

import sys,shelve as S
x,A,E=S.open("x"),sys.argv,exit
A[1]<'2'and E(x.clear())or'3'>A[1]and E(x.__setitem__(A[2],1))or'4'>A[1]and E(x.__delitem__(A[2]))or E(A[2]in x)

You need to create the temporary file like this

python -c 'import shelve;shelve.open("x","c")'
\$\endgroup\$
1
\$\begingroup\$

Ruby - 146 characters

a,b=ARGV
File.open('x','a+'){|f|s=eval(f.read)||[]
s=[]if a=='1'
s+=[b]if a=='2'
s-=[b]if a=='3'
f.puts s.inspect
exit a=='4'?(s.index(b)?0:1):0}
\$\endgroup\$
1
\$\begingroup\$

PHP - 204 characters

<?
$s=unserialize(file_get_contents('f'));
$a=$argv;
$o=$a[1]--;
$a=$a[2];
--$o?(--$o?(--$o?die(!isset($s[$a])+0):$s=array_diff_key($s,array($a=>1))):$s[$a]=1):$s=array();
file_put_contents('f',serialize($s));

Added some linebreaks to make it a tad more readable. This throws a warning to screen when run for the first time, but otherwise, it does as asked.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.