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\$
  • \$\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 '12 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 '12 at 19:24
  • \$\begingroup\$ Someone should solve this without using regular expressions :) \$\endgroup\$ – beary605 Aug 9 '12 at 20:05
  • \$\begingroup\$ Could you please explain the last two lines in your question or show an example? \$\endgroup\$ – Rob Aug 10 '12 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 '12 at 4:08
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])
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Only problem is, you have to actually run the code to get the variables. \$\endgroup\$ – Joel Cornett Aug 10 '12 at 0:43
  • \$\begingroup\$ I have put in another test case, please modify your answer to fit it. \$\endgroup\$ – beary605 Aug 10 '12 at 1:09
  • \$\begingroup\$ Alright, I've changed my answer. \$\endgroup\$ – Fraxtil Aug 10 '12 at 4:08
  • \$\begingroup\$ Very interesting... I've never heard of a code object or the compile built-in before. \$\endgroup\$ – beary605 Aug 10 '12 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 '12 at 23:28
2
\$\begingroup\$

Haskell, 2

[]

Only if you take the word "variable" literally.

|improve this answer|||||
\$\endgroup\$
  • 1
    \$\begingroup\$ For all those not knowing Haskell: It actually doesn't have any variables; anything is constant. \$\endgroup\$ – FUZxxl Aug 13 '12 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=>
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I have put in another test case, please modify your answer to fit it. \$\endgroup\$ – beary605 Aug 10 '12 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__)))
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ This also prints integers and words inside of strings... \$\endgroup\$ – Fraxtil Aug 10 '12 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\$ – Joel Cornett Aug 10 '12 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.

|improve this answer|||||
\$\endgroup\$
  • \$\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 '12 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 '12 at 17:32
  • 1
    \$\begingroup\$ This is code golf. Cheating is encouraged. \$\endgroup\$ – captncraig Aug 14 '12 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
|improve this answer|||||
\$\endgroup\$
0
\$\begingroup\$

MATLAB, 12

eval('<PROGRAM STRING HERE>');who
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I have put in another test case, please modify your answer to fit it. \$\endgroup\$ – beary605 Aug 10 '12 at 1:11
  • \$\begingroup\$ @beary605 no need to change anything :) \$\endgroup\$ – Griffin Aug 10 '12 at 1:29
  • \$\begingroup\$ Even better for you. ;D \$\endgroup\$ – beary605 Aug 10 '12 at 1:58
  • \$\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 '12 at 13:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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