5
\$\begingroup\$

Given some code in your language as a string, find and display all the variable names.

Examples in pseudocode:

a=2
b=3
for(i, 0->9) do b=b-10
if a=b then write "a equals b"

Returns: a b i

abcdefgh=20000000000000
bcdifhgs="hello"
if abcdefgh=bcdifhgs then da44="hax"
if abcdefgh*2=da44 then write da44

Returns: abcdefgh bcdifhgs da44

2=3
3=5
5=7
if 2=7 then exit

Returns:

a=2
while True do b=3

Returns: a b

Shortest code wins.

For stack-based languages, display the highest height of the stack.
For memory cell based languages, display all the memory cells that have been changed.

\$\endgroup\$
7
  • \$\begingroup\$ How is the code given, as a string input to our program, or are we to append our code to the 'input' program? \$\endgroup\$
    – Griffin
    Aug 9, 2012 at 17:04
  • 3
    \$\begingroup\$ I was soo excited to answer with an empty brainfuck program until I read the last line. \$\endgroup\$
    – captncraig
    Aug 9, 2012 at 19:24
  • \$\begingroup\$ Someone should solve this without using regular expressions :) \$\endgroup\$
    – beary605
    Aug 9, 2012 at 20:05
  • \$\begingroup\$ Could you please explain the last two lines in your question or show an example? \$\endgroup\$
    – anon
    Aug 10, 2012 at 2:38
  • \$\begingroup\$ @MikeDtrick: Stack-based: push 2 items pull 1 item push 2 items pull 3 items will return 3. Memory-cell: think Brainfuck, and all cell values which have been changed by + or -. \$\endgroup\$
    – beary605
    Aug 10, 2012 at 4:08

7 Answers 7

5
\$\begingroup\$

Python 3, 73 66 86

Now follows the updated test cases:

import sys
print(*set(compile(sys.argv[1],'','exec').co_names)-set(dir(__builtins__)))

Note that this also prints the names of non-builtin objects and methods / attributes of objects (e.g. if you use sys.argv in the input code it'll print sys and argv). Still, it does technically fit the test cases.

Assuming we're allowed to simply run the code, it can be done in 66 characters. Note that this fails the while True test case and, unlike the above solution, does not print things like sys and argv:

import sys
print(*(lambda:(exec(sys.argv[1]),set(locals())))()[1])
\$\endgroup\$
5
  • \$\begingroup\$ Only problem is, you have to actually run the code to get the variables. \$\endgroup\$ Aug 10, 2012 at 0:43
  • \$\begingroup\$ I have put in another test case, please modify your answer to fit it. \$\endgroup\$
    – beary605
    Aug 10, 2012 at 1:09
  • \$\begingroup\$ Alright, I've changed my answer. \$\endgroup\$
    – ashastral
    Aug 10, 2012 at 4:08
  • \$\begingroup\$ Very interesting... I've never heard of a code object or the compile built-in before. \$\endgroup\$
    – beary605
    Aug 10, 2012 at 6:26
  • \$\begingroup\$ This is really the only answer which runs correctly for the last test case, so answer to you! \$\endgroup\$
    – beary605
    Aug 18, 2012 at 23:28
2
\$\begingroup\$

Haskell, 2

[]

Only if you take the word "variable" literally.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ For all those not knowing Haskell: It actually doesn't have any variables; anything is constant. \$\endgroup\$
    – FUZxxl
    Aug 13, 2012 at 17:23
1
\$\begingroup\$

Ruby

Kind of cheating, I guess... If code contains Ruby code, then:

pre = global_variables
eval code
(global_variables - pre + local_variables + self.instance_variables - [:code, :pre]).each do |x|
  puts x.to_s
end

Example: code = "a = 3; @b = 5; $c = 6, @@d = 10"

Output:

$c
@b

Works only with global and instance vars so far.

zsh

set > /tmp/set.1
eval $code
set > /tmp/set.2
diff -a /tmp/set.1 /tmp/set.2 | grep -vE "HISTCMD|LINENO|RANDOM|SECONDS|pipestatus" | grep -E ">[^=]+"

Example:

$code = 'zzz=3; xxx="hello"'

Output

> xxx=hello
> zzz=3

Clojure, 53

(pr(map #(last %)(re-seq #"\( *def +([a-z-])+"code))

Example:

user=> (def code "(def a 1) (     def    b     ( +  3 5 )))")
#'user/code
user=> (pr(map #(last %)(re-seq #"\( *def +([a-z-]+)"code)))
("a" "b")nil
user=>
\$\endgroup\$
1
  • \$\begingroup\$ I have put in another test case, please modify your answer to fit it. \$\endgroup\$
    – beary605
    Aug 10, 2012 at 1:10
1
\$\begingroup\$

Python 104

import sys,re,keyword
print(set(re.findall(r"\b\w+\b",sys.argv[1]))-set(keyword.kwlist+dir(__builtins__)))
\$\endgroup\$
2
  • \$\begingroup\$ This also prints integers and words inside of strings... \$\endgroup\$
    – ashastral
    Aug 10, 2012 at 19:53
  • \$\begingroup\$ @Fraxtil: Yes, I realized this the other day :/ Still trying to think of a way to handle string literals without adding to much to the character count. \$\endgroup\$ Aug 10, 2012 at 21:06
1
\$\begingroup\$

HQ9+ (or H9+), 0

Is cheating allowed? In this case, the solution is a program of zero length, because the language has no variables, and has no memory cells, stack or any other form of storage. So it outputs nothing.

First I wanted to write Brainf*ck, but then I realized the "memory cell" rule.

\$\endgroup\$
3
  • \$\begingroup\$ Actually, you have a memory cell. (Remember that nice operator called + [increment the counter]? It's pretty pointless since you can't read out the counter at all, but the counter is definitly a variable. ) \$\endgroup\$
    – FUZxxl
    Aug 13, 2012 at 17:24
  • \$\begingroup\$ I always assumed it is the program counter. If you require to also print the PC, it would invalidate all other answers, because none of them print it :) \$\endgroup\$
    – vsz
    Aug 13, 2012 at 17:32
  • 1
    \$\begingroup\$ This is code golf. Cheating is encouraged. \$\endgroup\$
    – captncraig
    Aug 14, 2012 at 20:51
1
\$\begingroup\$

Python, 111

I am pretty new to code golf.. tips are appreciated, but here is an alternative approach

import ast as a
s=set()
v=a.NodeVisitor
v.visit_Name=lambda t,n:s.add(n.id)
v().visit(a.parse(input()))
print s
\$\endgroup\$
-1
\$\begingroup\$

MATLAB, 12

eval('<PROGRAM STRING HERE>');who
\$\endgroup\$
4
  • \$\begingroup\$ I have put in another test case, please modify your answer to fit it. \$\endgroup\$
    – beary605
    Aug 10, 2012 at 1:11
  • \$\begingroup\$ @beary605 no need to change anything :) \$\endgroup\$
    – Griffin
    Aug 10, 2012 at 1:29
  • \$\begingroup\$ Even better for you. ;D \$\endgroup\$
    – beary605
    Aug 10, 2012 at 1:58
  • 1
    \$\begingroup\$ I'm fairly certain, although can't test it, that if the <PROGRAM STRING HERE> is a piece of code that never terminates that your program will never print the variables. \$\endgroup\$
    – Matt
    Aug 11, 2012 at 13:35

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.