Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

You're tasked with writing two programs. Program A must print out nothing on all inputs except when program B is input, in which case it should print 1. Program B must print out 1 on all inputs except when program A is input, in which case it should print nothing.

Scoring:

  • +1 For each character from both programs.
  • Lowest score wins.
share|improve this question
3  
Is this quine-ish enough to tag it as quine? It certainly seems so to me. –  Quincunx Jan 9 at 20:26
    
As the first two answers posted indicate, "being" another program is not terribly well defined in this descriptions. And, I'm with @Quincunx that this has something very much like the quine-nature. –  dmckee Jan 9 at 22:25
    
@Quincunx I've added the quine tag. –  Timtech Jan 9 at 23:45
1  
@Quincunx true, but nobody is doing that so far, unless you also call a quine any program that reads its source code from disk and prints it out :p –  aditsu Jan 10 at 4:59
1  
@aditsu I much dislike those answers. I think I'll post a very suboptimal answer that does not do that. I personally feel that reading source code through files is cheating; programs should work anywhere! –  Quincunx Jan 10 at 5:11
show 6 more comments

12 Answers

up vote 6 down vote accepted

GTB, 25

Executed from a TI-84 calculator

Program A

`_@_eq;"$w;&

Program B

`_@_eq;"$#w;&

Explanation

`_ Input a string

@_eq;" Check if it equals the source code (# is automatically stripped along with lowercase letters)

$w;& If so, display 1 (otherwise nothing) [for B it's $#w;& - if not, display 1 (otherwise nothing)]

share|improve this answer
add comment

Bash - 32 characters

Script A - 16 characters

cmp -s b&&echo 1

Script B - 16 characters

cmp -s a||echo 1

Usage

$> echo "foo" | ./a
$> cat b | ./a
1
$> echo "foo" ./b
foo ./b
$> cat a | ./b
share|improve this answer
add comment

Ruby, 54

A

$><<1if$<.read==IO.read(?B)

B

$><<1if$<.read!=IO.read(?A)

examples:

bash-3.2$ ruby A < A
bash-3.2$ ruby A < B
1bash-3.2$ ruby B < A
bash-3.2$ ruby B < B
1bash-3.2$ 
share|improve this answer
add comment

J (62)

Since you didn't forbid this...

Store the programs as A and B respectively.

Program A (30):

exit echo#~(1!:1<'B')-:1!:1[3

Program B (32):

exit echo#~-.(1!:1<'A')-:1!:1[3

How it works (Program B, A is similar):

  • 1!:1[3: read stdin
  • 1!:1<'A': read file A
  • -:: see if they are equal
  • -.: negate the result
  • #~: replicate the result by itself (so, 1 results in one 1 and 0 results in zero 0s, i.e. nothing)
  • echo: output
  • exit: exit (the J interpreter does not exit by default when it reaches the end of the file)
$ jconsole A <B
1
$ jconsole A <foo
$ jconsole B <A
$ jconsole B <foo
1
$
share|improve this answer
    
Can you give a short explanation of what this does? –  ike Jan 9 at 20:39
    
@ike: did so _______ –  marinus Jan 9 at 20:43
add comment

Haskell - WITHOUT loading source - 478 644 characters

This assumes getContents ALWAYS ends with a newline and so drops the final character without checking because I don't feel like escaping it

A

main=interact$($'1').replicate.(1-).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='-'='*'|n=='*'='-'|True=n;d="main=interact$($'1').replicate.(1-).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='-'='*'|n=='*'='-'|True=n;d="

B

main=interact$($'1').replicate.(1*).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='*'='-'|n=='-'='*'|True=n;d="main=interact$($'1').replicate.(1*).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='*'='-'|n=='-'='*'|True=n;d="

It works like a standard quine, but swapping - for * to get the other program (avoiding those characters elsewhere).

The following test prints as expected (replacing main=interact$ with a= and b=)

main=do
  putStrLn "START"
  putStrLn$a "FOO"
  putStrLn$a "main=interact$($'1').replicate.(1*).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='*'='-'|n=='-'='*'|True=n;d=\"main=interact$($'1').replicate.(1*).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='*'='-'|n=='-'='*'|True=n;d=\"\n"
  putStrLn$b "FOO"
  putStrLn$b "main=interact$($'1').replicate.(1-).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='-'='*'|n=='*'='-'|True=n;d=\"main=interact$($'1').replicate.(1-).fromEnum.(/=map r(d++shows d[toEnum 10]))where r n|n=='-'='*'|n=='*'='-'|True=n;d=\"\n"
  putStrLn "END"

-

START

1
1

END
share|improve this answer
    
Also if there's a preferred way to format monolithic single line functions that would be handy, meta.stackoverflow.com/questions/22186/… doesn't appear to cover it –  Toeofdoom Jan 10 at 14:08
add comment

Python 2.7 - 82

File A (literally named just a):

if raw_input()==open('b').read():print 1

File B (literally named just b):

if raw_input()!=open('a').read():print 1
share|improve this answer
    
Total abuse there without the .py - does that even work? –  Timtech Jan 9 at 23:41
    
I'm sure @LegoStormtroopr would be running in the same manner as my Ruby examples posted here, a few minutes earlier. ;-) –  Darren Stone Jan 9 at 23:55
    
@Timtech It does if you run them from the command line as python a. –  Lego Stormtroopr Jan 10 at 0:17
    
I meant is it possible to even generate a file without an extension? –  Timtech Jan 10 at 0:21
4  
Of course it is? If you are on a Posix machine touch a will create an empty file if you have permissions. For extra cruel fun you can even do touch \~ which creates a file named with a single tilde (~) - then watch as someone foolhardedly tries to remove it ;) –  Lego Stormtroopr Jan 10 at 0:35
add comment

Ruby, 166 chars, no reading source

A:

(gets(p)==<<2.tr('&|','|&')*2+'2')&&p(1)
(gets(p)==<<2.tr('&|','|&')*2+'2')&&p(1)
2

B:

(gets(p)==<<2.tr('|&','&|')*2+'2')||p(1)
(gets(p)==<<2.tr('|&','&|')*2+'2')||p(1)
2

Make sure your text editor doesn't save with a trailing newline.

Usage (example):

 $ ruby know_a.rb know_b.rb 
1
 $ ruby know_a.rb know_a.rb 
 $ ruby know_b.rb know_a.rb 
 $ ruby know_b.rb know_b.rb 
1

Each program constructs the source of the other program using a HEREdoc and string transforms, then compares the result to the input.

share|improve this answer
    
This was easy enough to write, but now some part of my brain that doesn't understand recursion is insisting it can be optimized but has no idea how. –  histocrat Jan 10 at 20:05
    
What is p? And where does the heredoc end? –  aditsu Jan 10 at 21:32
    
p is a built-in ruby method that prints the arguments passed to it, then returns those arguments, making it useful for golfed output. When called with no arguments it returns nil. The argument to gets is a delimiter, so passing p results in a nil delimiter which means it reads STDIN until it gets to EOF. The heredoc expression is <<2, so it ends at (and does not include), the 2 at the end of the file. –  histocrat Jan 10 at 21:40
    
The use of 2 as the heredoc delimiter is a traditional bit of obfuscation. It can be almost any string. –  histocrat Jan 10 at 21:43
    
Is the content of the heredoc evaluated somehow? –  aditsu Jan 10 at 21:49
show 5 more comments

Haskell - 138

Not really a good answer, but wanted to make both programs use the same source. Could save some chars by renaming the file, but it's not going to make this a winning solution so I don't think it's worth it.

import System.Environment
import Control.Monad
main=do{i<-getContents;p<-getProgName;f<-readFile "ab.hs";when((f==i)/=(p=="B"))(print 1)}

Compile this source as both A and B.

Test:

% ghc -o A ab.hs
[1 of 1] Compiling Main             ( ab.hs, ab.o )
Linking A ...
% cp A B
% ./A < ab.hs
1
% ./B < ab.hs
% ./A < ab.hi
% ./B < ab.hi
1
share|improve this answer
    
why compile twice into A, and then copy A to B? –  mniip Jan 9 at 22:45
    
That was a mistake by my part when copypasting the code. Thanks for pointing that out. Will fix. –  shiona Jan 9 at 22:46
add comment

Node.js - 142 characters

Script | (otherwise known as Script A) - 80 characters

f=require('fs').readFileSync;f('/dev/stdin','hex')==f('&','hex')&&console.log(1)

Script & (otherwise known as Script B) - 62 characters

eval(require('fs').readFileSync('|','utf8').replace(/&/g,'|'))

Usage

# \| is Script A
# \& is Script B

$> echo "foo" | node \| 
$> cat \& | node \| 
1
$> echo "foo" | node \& 
1
$> cat \| | node \&

Description

Script B reads the contents of Script A and evals it after swapping the file names and the and operator to an or.

I named the files & and | so I can perform a single replace in Script B.

share|improve this answer
add comment

Python 3 - 102 characters

Prints 1 if the input is the same as program 2, otherwise nothing:

if input()==open('a.py').read():print('1')

Prints 1 if input is not the same as program 1, otherwise nothing:

if input()==open('a.py').read():print('1')
share|improve this answer
    
Can't the whitespace be removed? Also you can shorten the scripts from t.py and tt.py to a.py and b.py. –  Timtech Jan 10 at 1:28
    
@Timtech Sure, good idea. Also, I wasn't counting white-space - that is just there for readability. The new-lines cannot be removed though. –  hosch250 Jan 10 at 1:40
    
Yes, I am aware of Python's newline sensitivity. –  Timtech Jan 10 at 2:33
    
Only one of the newlines can really be removed, that after the colon. The others would need semicolons added, so there is no advantage to removing those newlines. –  AJMansfield Jan 10 at 2:39
    
@AJMansfield Yes, I know, but I didn't count newlines anyway. –  hosch250 Jan 10 at 2:40
show 4 more comments

bash/grep — 59 chars

51 chars if we only count the actual program string.

$ a='grep -cx "$b" | grep -x 1'
$ b='grep -vcx "$a" | grep -x 1'
$ echo 'foo' | eval $a
$ echo $b | eval $a
1
$ echo 'foo' | eval $b
1
$ echo $a | eval $b
share|improve this answer
add comment

R (62 chars)

i=identical
A=function(x)if(i(x,B))1
B=function(x)if(!i(x,A))1

produces:

> A(123)
> A(A)
> A(B)
[1] 1
> B(123)
[1] 1
> B(A)
> B(B)
[1] 1

Meta comment: R fairs relatively bad on code golf as there is no shortcut to function...

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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