Write a program to perform set operations.

4

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

Alexandru

Posted 2011-02-25T20:02:50.623

Reputation: 5 485

@Joey. Yes. That's why you should use a file. – Alexandru – 2011-02-26T00:11:00.067

Your 4th test assert an exit code of 1 which is not according to the specification (where 3 would always return 0). – Joey – 2011-02-26T16:30:12.837

@Joey: thank you. I missed that. – Alexandru – 2011-02-26T16:38:55.400

Answers

7

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.

Nabb

Posted 2011-02-25T20:02:50.623

Reputation: 2 540

I find it brilliant that you use separate files for each argument. – Eelvex – 2011-02-26T08:32:33.463

2

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

gnibbler

Posted 2011-02-25T20:02:50.623

Reputation: 14 170

2

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

Eelvex

Posted 2011-02-25T20:02:50.623

Reputation: 5 204

1

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.

Juan

Posted 2011-02-25T20:02:50.623

Reputation: 2 738

1

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.

Peter Taylor

Posted 2011-02-25T20:02:50.623

Reputation: 41 901

If you add number '123' and then query for '23' what's the exit code? – Eelvex – 2011-02-25T23:43:11.390

@Eelvex, good catch. I had -x on one grep but not on the other. – Peter Taylor – 2011-02-26T07:08:21.430

1

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}

david4dev

Posted 2011-02-25T20:02:50.623

Reputation: 665