20
\$\begingroup\$

In this challenge, the goal is to find the values of some variables after a number of assignments are done. An example input:

a = 5
b = 4
c = a = b
a = 2
b = a

This would result in:

a = 2
b = 2
c = 4

Each statement will be one of the following:

  • A variable name ([a-z_]+)
  • A numeric value ([0-9]+)
  • An assignment operation, with a variable name on the left and a statement on the right

You may assume that the input will be a list of statements, formatted however you want. Variable names will have differing lengths (if you need a hard value to gold within, assume 16 chars max).

Note that statements can contain more or less than one assignment (such as a, 23, or a = b = c = 4), and that variables can appear that are never assigned to. Assume no undefined variables are used as values in an assignment (such as a = undefined_variable), and that no variable will be on both sides of an assignment (such as a = a or a = a = 1).

You can take input any way you wish (such as a string with a character to delimit statements, a list formatted as [["a", 5], ["b", "a"]], etc.), and output can be in any consistent format (such as a hash map of names to values, or a list of values in the order that the variables first appeared).

Test cases:

a = 5 -> a = 5
b = 512, c = a = 2 -> a = 2, b = 512, c = 2
def, 2, e = 8, 101 -> e = 8
 -> 
a -> 
fgh = 4, i = 3, fgh = i -> fgh = 3, i = 3
j = k = l = m = n = 14 -> j = 14, k = 14, l = 14, m = 14, n = 14
s = t = u = 6, t = v = 7 -> s = 6, t = 7, u = 6, v = 7
o = 3, o = p -> [undefined]
q = r -> [undefined]
w = w = 2 -> [undefined]
x = 4, x = x -> [undefined]

This is , so shortest answer per language wins!

asked Sep 21, 2020 at 23:01
\$\endgroup\$
3
  • 8
    \$\begingroup\$ Also note to answers that eval and the like is unlikely to work, as the variable could be named like a keyword in your language. \$\endgroup\$ Commented Sep 21, 2020 at 23:13
  • 1
    \$\begingroup\$ Should I handle empty input (zero statements)? \$\endgroup\$ Commented Sep 22, 2020 at 0:26
  • \$\begingroup\$ @Bubbler That's a tough one. I think I'm going to say yes, and it would have the same output as 23 or a would (nothing). I think most answers already work that way anyway. \$\endgroup\$ Commented Sep 22, 2020 at 2:05

23 Answers 23

9
\$\begingroup\$

APL (Dyalog Unicode), 22 bytes

{n⊣⍵{0::0⋄⍵⍎⍺} ̈n←⎕NS⍬}

Try it online!

Takes a list of statements in the form of a←b←3, and returns a namespace which is essentially a hashmap of variable names to values. You can't print all the contents of it directly, but you can inspect individual variables like ns.somevar or list all names using ns.⎕NL ̄2.

Oh, and APL doesn't have any alphanumeric-only keywords!

{n⊣⍵{0::0⋄⍵⍎⍺} ̈n←⎕NS⍬} ⍝ ⍵: list of statements
 n←⎕NS⍬ ⍝ Create an empty namespace
 ⍵{ } ̈ ⍝ For each statement...
 ⍵⍎⍺ ⍝ Try executing the statement inside the namespace
 0::0⋄ ⍝ ignoring any errors (undefined name)
 n⊣ ⍝ Return the populated namespace
answered Sep 22, 2020 at 0:08
\$\endgroup\$
5
  • 2
    \$\begingroup\$ Right language for the job I guess! \$\endgroup\$ Commented Sep 22, 2020 at 0:11
  • \$\begingroup\$ what does the SRC THIS part do? \$\endgroup\$ Commented Sep 22, 2020 at 0:43
  • 2
    \$\begingroup\$ @Jonah It's not SRC THIS, it's ⎕SRC (system function) ⎕THIS (system variable). Normally a function should be defined on its own line as f←{...}. To use the code section on TIO as the byte counter, the raw function {...} without assignment is fetched as source code using ⎕SRC ⎕THIS and eval'd into a function, then assigned to f. \$\endgroup\$ Commented Sep 22, 2020 at 0:53
  • \$\begingroup\$ -1: {⊃⍵{0::⍵⋄⍵⊣⍵⍎⍺}¨⎕NS⍬} Try it online! (though a full program works, ⊃⎕{0::⍵⋄⍵⊣⍵⍎⍺}¨⎕NS⍬, it is awkward to use) \$\endgroup\$ Commented Sep 22, 2020 at 5:58
  • \$\begingroup\$ @Adám Doesn't work with zero-statement input. \$\endgroup\$ Commented Sep 22, 2020 at 6:00
8
\$\begingroup\$

Python (削除) 3 (削除ここまで) 2, (削除) 80 (削除ここまで) (削除) 75 (削除ここまで) 69 bytes

-5 bytes thanks to @Sisyphus
-6 bytes thanks to @xnor

g={}
for s in input():
 k=s.pop()
 for n in s:g[n]=g.get(k,k)
print g

Try it online!

Takes input as a list of lists of terms, returns a dict of variable name to value.

Explanation

def f(x,g={}): # Save a few bytes by defining g as a default argument.
 for s in x:
 k=s.pop(-1) # Take the last term, which is the value we'll be using.
 for n in s: # For all *other* values:
 g[n]=g.get(k,k) # .get(k, k) means "get the value called k, if not found use k raw" (numbers will not be found)
 return g

Note that it never actually differentiates between numbers and variables, just trusts that the input won't try to assign to a number. This means you can actually use it to assign to a number - this input:

[9, 5],
['b', 9],
['c', 'a', 'b'],
['a', 2],
['b', 9]

Will result in this output:

{9: 5, 'b': 5, 'c': 5, 'a': 2}
user
4572 gold badges21 silver badges71 bronze badges
answered Sep 21, 2020 at 23:11
\$\endgroup\$
6
  • \$\begingroup\$ This fails for the third test case \$\endgroup\$ Commented Sep 21, 2020 at 23:21
  • \$\begingroup\$ @cairdcoinheringaahing Yes, see edit. \$\endgroup\$ Commented Sep 21, 2020 at 23:21
  • \$\begingroup\$ Bad choice of test case, it still fails for variables with no assignment \$\endgroup\$ Commented Sep 21, 2020 at 23:23
  • 1
    \$\begingroup\$ You can iterate over input() directly, and also use that pop uses the -1 index as default: Try it online!, \$\endgroup\$ Commented Sep 22, 2020 at 3:24
  • \$\begingroup\$ Note that your original answer could have been 35 bytes with exec(x,{},g), since exec does not add __builtins__ to the locals dictionary. (This is still invalid) \$\endgroup\$ Commented Sep 22, 2020 at 7:16
5
\$\begingroup\$

J, 66 bytes

33 bytes for the _ =: 1 special case ...

(rplc&('a0';'_')@}.~&_6;".)&>@r0[0!:110@rplc&('_';'a0')[r0=:4!:5@1

Try it online!

How it otherwise works

(_6&}.;".)&>@r0[0!:110[r0=:4!:5@1

It's a mess! m!:n are special functions, that do stuff depending on m and n.

  • r0=:4!:5@1: "4!:5 (1) produces a list of global names assigned since the last execution of 4!:5." Store as r0, so we can execute it again cheaply while it won't be overwritten.
  • 0!:110 execute input string as script, ignoring any output/errors (so predefined values won't cause harm.)
  • r0 execute 4!:5@1 again, get boxed list of changed variables
  • &> unbox and ...
  • ". execute each variable to get its value
  • _6}&. drop last 6 characters from the variable (which contain the namespace _base_.)
  • ; join name and result together
answered Sep 22, 2020 at 1:01
\$\endgroup\$
6
  • \$\begingroup\$ Fails for _ =: 1 \$\endgroup\$ Commented Sep 22, 2020 at 1:10
  • \$\begingroup\$ @Sisyphus _ isn't a valid variable name in J; it's the built in number infinity. \$\endgroup\$ Commented Sep 22, 2020 at 1:13
  • 1
    \$\begingroup\$ @Jonah however the spec requires you support [a-z_]+, no? \$\endgroup\$ Commented Sep 22, 2020 at 1:13
  • \$\begingroup\$ You're right. It's only impossible with this approach, not with J itself. \$\endgroup\$ Commented Sep 22, 2020 at 1:16
  • \$\begingroup\$ @Sisyphus Ugh, and I thought I was handling all edge cases. Fixed for now, maybe tomorrow I'll have a better approach than just substituting... \$\endgroup\$ Commented Sep 22, 2020 at 1:36
4
\$\begingroup\$

JavaScript (ES6), 81 bytes

Expects a string in the format described in the challenge. Returns an array of [name, value] pairs.

s=>Object.keys(o={},eval(s.replace(/[_-z]+/g,"o.X$&"))).map(k=>[k.slice(1),o[k]])

Try it online!

How?

We define an object o initially empty and add the prefix "o.X" to all variable names in the input string.

Example:

/* before */ "s = t = u = 6, t = v = 7"
/* after */ "o.Xs = o.Xt = o.Xu = 6, o.Xt = o.Xv = 7"

We need the leading X to prevent the reserved property __proto__ from being overridden this way.

Provided that the input string is in the expected format -- which is guaranteed by the challenge rules -- the transformed string can be safely eval()'uated. We then iterate on the keys of o to build a list of pairs consisting of 1) the key name without the leading X and 2) the final value associated to the key.

Without the __proto__ issue, this could be done in just 45 bytes without any post-processing:

s=>(eval(s.replace(/[_-z]+/g,"o.$&",o={})),o)

Try it online!

answered Sep 22, 2020 at 5:25
\$\endgroup\$
2
  • \$\begingroup\$ I notice on MDN Object.keys take one arg, so are we relying on the 2nd arg being ignored and left to right arg evaluation? \$\endgroup\$ Commented Sep 22, 2020 at 12:40
  • 1
    \$\begingroup\$ @Jonah Yes and yes. :-) \$\endgroup\$ Commented Sep 22, 2020 at 12:47
4
\$\begingroup\$

Wolfram Language (Mathematica), (削除) 55 (削除ここまで) (削除) 51 (削除ここまで) (削除) 43 (削除ここまで) 42 bytes

($=<||>;Fold[($@#2=#/.$)&]@*Reverse/@#;$)&

Try it online!

-8 thanks to w123

answered Sep 22, 2020 at 0:03
\$\endgroup\$
1
  • \$\begingroup\$ You can shorten the lookup code $@#/._@__:># to #/.$ -- Associations can be used like rules. \$\endgroup\$ Commented Sep 23, 2020 at 15:08
3
\$\begingroup\$

Python 3.9rc2, 67 bytes

def f(x):
 g={}
 for*u,k in x:g|={n:g.get(k,k)for n in u}
 return g

No TIO link, as TIO doesn't support Python 3.9.

Borrows ideas from Artemis' answer, with the following improvements:

  • We can use an iterable unpack *u,k in the for loop.
  • In Python 3.9 we can merge dicts using a|=b, which is much shorter than the old a.update(b) and {**a,**b} methods.
answered Sep 22, 2020 at 3:08
\$\endgroup\$
4
  • \$\begingroup\$ Having a defaulted function parameter which is mutable means the function is not reusable without passing that default, so I think it has to go in the function body instead, right? \$\endgroup\$ Commented Sep 22, 2020 at 12:28
  • \$\begingroup\$ @JonathanAllan, I don't know Python but wouldn't g only exist within the scope of the function, meaning it would reset to the default {} with each subsequent call? \$\endgroup\$ Commented Sep 22, 2020 at 19:21
  • 1
    \$\begingroup\$ @Shaggy no, I think it's in the caller's scope. Indeed a function like this is not re-usable. Here is a simple example of a mutable object (a dictionary) which does not get set back to the default on the second call. \$\endgroup\$ Commented Sep 22, 2020 at 22:37
  • 1
    \$\begingroup\$ @JonathanAllan indeed you're right. I've fixed this (luckily it only cost a byte). I think I've been caught by this even in non-golf contexts before! \$\endgroup\$ Commented Sep 23, 2020 at 0:24
3
\$\begingroup\$

Python 3, (削除) 159 (削除ここまで) (削除) 141 (削除ここまで) (削除) 152 (削除ここまで) 128 bytes

def f(s):
	g={}
	for k in s:
		if'='in k:
			*v,l=k.split('=')
			for r in v:
				try:g[r]=int(l)
				except:g[r]=g[l]
	return g

Try it online!

-18 bytes thanks to pxeger

+11 bytes thanks to Shaggy for pointing out a bug

-24 bytes thanks to ovs

Python really isn't my strong suit for golfing :/ Note the use of tabs rather than spaces, so the indentation levels are still a single byte each. Takes input as a list of lines with assignments separated by = (no spaces) and returns a dictionary of variables and values

answered Sep 21, 2020 at 23:18
\$\endgroup\$
8
  • \$\begingroup\$ 141 bytes by replacing the filter with an if-statement, and you also don't need the return statement \$\endgroup\$ Commented Sep 22, 2020 at 7:59
  • \$\begingroup\$ @pxeger Nice, edited that in! Thanks \$\endgroup\$ Commented Sep 22, 2020 at 12:47
  • \$\begingroup\$ I think this might suffer from the same problem Jonathan raised here. \$\endgroup\$ Commented Sep 23, 2020 at 21:47
  • \$\begingroup\$ @Shaggy So it does. Corrected \$\endgroup\$ Commented Sep 23, 2020 at 21:56
  • \$\begingroup\$ Do you really need ast.literal_eval? I think you can just replace it with int. \$\endgroup\$ Commented Sep 23, 2020 at 22:15
3
\$\begingroup\$

Batch, (削除) 331 (削除ここまで) (削除) 317 (削除ここまで) 72 bytes

@setlocal
@for /f "delims==" %%a in ('set')do @set %%a=
@set/a%*
@set

Takes a comma-separated list of assignments on the command line. Explanation:

@setlocal

Don't modify the parent environment.

@for /f "delims==" %%a in ('set')do @set %%a=

Delete all variables, including predefined variables such as PATH. We're only using shell builtins, so we don't need them.

@set/a%*

Evaluate the assignments.

@set

List all of the resulting variables.

answered Sep 22, 2020 at 0:17
\$\endgroup\$
4
  • \$\begingroup\$ I already have an environment variable beginning with _ which would confuse the code otherwise I guess you could assume a clean environment where such environment variables do not exist? Though it'll make it harder to test the code. \$\endgroup\$ Commented Sep 22, 2020 at 0:23
  • \$\begingroup\$ @Bubbler I know that full programs don't normally have to worry about reusability because their state doesn't normally persist, but Batch scripts are more like functions in that regard, so I feel I shouldn't rely on the caller resetting the environment every time. \$\endgroup\$ Commented Sep 22, 2020 at 8:38
  • \$\begingroup\$ @Bubbler Actually I could just clean the environment myself, after I use setlocal to avoid destroying it. \$\endgroup\$ Commented Sep 24, 2020 at 6:51
  • 1
    \$\begingroup\$ @Bubbler ... and taking that to the logical extreme, I don't need any of the original environment at all, so... \$\endgroup\$ Commented Sep 24, 2020 at 7:24
2
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 183 bytes

	T =TABLE()
N	X =INPUT	:F(O)
R	X SPAN(&LCASE '_') . Y (' ' | RPOS(0)) . Z ='T<"' Y '">' Z	:S(R)
	EVAL(X)	:(N)
O	A =CONVERT(T,'ARRAY')
I	I =I + 1
	OUTPUT =A<I,1> ' = ' A<I,2>	:S(I)
END

Try it online!

Takes input separated by newlines with spaces between the =, and returns in the same format.

answered Sep 22, 2020 at 0:43
\$\endgroup\$
2
\$\begingroup\$

Ruby, 63 bytes

def f(a)
a.reduce({}){|m,x|*r,k=x
r.map{|y|m[y]=m[k]||k}
m}
end

Try it online!

I rarely golf in Ruby (tips appreciated) but I use it for work, and I liked Artemis's clean answer so much that I decided to see what a translation into ruby would look like.

answered Sep 22, 2020 at 3:34
\$\endgroup\$
2
\$\begingroup\$

Scala, 98 bytes

_./:(Map[String,String]()){case(m,a::b)=>val x=m.getOrElse(a,a);(m/:b.map(_->x))(_+_)case(m,_)=>m}

Try it online!

The statements have to be reversed (List("2","b") for "b=2"). The solutions below can't handle empty input.

Scala, (削除) 96 (削除ここまで) 94 bytes

_./:(Map[String,String]()){(m,l)=>val x=m.getOrElse(l.last,l.last);(m/:l.init.map(_->x))(_+_)}

Try it online!

Takes a List[List[String]] and returns a Map[String,String]

Scala, 86 bytes

This is shorter, but the statements are reversed

_./:(Map[String,String]()){case(m,a::b)=>val x=m.getOrElse(a,a);(m/:b.map(_->x))(_+_)}

Try it online!

answered Sep 22, 2020 at 13:49
\$\endgroup\$
2
\$\begingroup\$

JavaScript, (削除) 52 (削除ここまで) 88 bytes

+36 bytes to handle a single fecking edge case :\

a=>a.map(a=>a.map(k=>o[0+k]=o[0+v]|v,v=a.pop()),o={})&&JSON.stringify(o).split`0`.join``

Try it online!

answered Sep 22, 2020 at 7:05
\$\endgroup\$
6
  • 2
    \$\begingroup\$ Unfortunately JS is the wrong language for this challenge because of its 'dicts are objects' paradigm: __proto__=1 fails. \$\endgroup\$ Commented Sep 22, 2020 at 7:26
  • \$\begingroup\$ @Sisyphus, I would assume that we don't have to handle variable names that aren't valid in our chosen language. Otherwise this is going to be impossible in a hell of a lot of languages. \$\endgroup\$ Commented Sep 22, 2020 at 8:35
  • \$\begingroup\$ @Shaggy Multiple answers have been invalidated because they use eval, exec or similar and thus fail for keywords. \$\endgroup\$ Commented Sep 22, 2020 at 12:30
  • \$\begingroup\$ @Artemisstilldoesn'ttrustSE, well feck it, anyway :( Implemented a quick and far too bulky fix for now. \$\endgroup\$ Commented Sep 22, 2020 at 16:18
  • 1
    \$\begingroup\$ @RedwolfPrograms, that's what the 0s are doing. I'm prepending a 0 to each variable name in the map and then later removing them with the split & join. \$\endgroup\$ Commented Sep 22, 2020 at 16:34
1
\$\begingroup\$

Retina 0.8.2, 85 bytes

G`=
+`=(.+(=.+))
2ドル¶1ドル
+rm`(^4円=(.+)¶(.+¶)*?.+=)(.+)$
1ドル2ドル
+m`^(.+)=.+¶((.+¶)*1円=)
2ドル

Try it online! Link includes test suite that converts the input from comma separated to newline separated assignments with no spaces. Explanation:

G`=

Ignore statements that have no assignments.

+`=(.+(=.+))
2ドル¶1ドル

Split up assignment chains into individual assignments.

+rm`(^4円=(.+)¶(.+¶)*?.+=)(.+)$
1ドル2ドル

Substitute the values of variables used on the right-hand side of assignments. The matching is performed right-to-left so that the most recent value is used.

+m`^(.+)=.+¶((.+¶)*1円=)
2ドル

Remove superseded assignments.

answered Sep 22, 2020 at 9:13
\$\endgroup\$
1
\$\begingroup\$

Java 10, 137 bytes

a->{var r=new java.util.TreeMap();for(var p:a)for(int l=p.length-1,i=l;i-->0;)r.put(p[i],p[l]instanceof Long?p[l]:r.get(p[l]));return r;}

Input as a Object-matrix (variables as Strings, values as Longs), output as a sorted HashMap.

Try it online.

Explanation:

a->{ // Method with Object-matrix parameter & TreeMap return
 var r=new java.util.TreeMap();// Create the result sorted HashMap
 for(var p:a) // Loop over each Object-list of the input-matrix:
 for(int l=p.length-1, // Integer `l`, set to the last index of the list
 i=l;i-->0;) // Inner loop `i` in the range (length-1, 0]:
 r.put( // Add to the result TreeMap:
 p[i], // The `i`'th value of the list as key
 p[l]instanceof Long? // If the last item is a Long:
 p[l] // Use that last item as value
 : // Else:
 r.get(p[l])); // Get the value of this last item from the
 // result-Map, and use that as value
 return r;} // Return the resulting TreeMap (sorted HashMap)
answered Sep 22, 2020 at 11:15
\$\endgroup\$
1
\$\begingroup\$

Red, (削除) 74 (削除ここまで) 69 bytes

func[b][context collect[forall b[if set-word? first t: b/1[keep t]]]]

Try it online!

Takes the input as a list of lists, in each of them = replaced with : (Red has set-words rather than assignment operator)

answered Sep 22, 2020 at 11:06
\$\endgroup\$
1
\$\begingroup\$

05AB1E, (削除) 30 (削除ここまで) 29 bytes

εRćÐþÊiU ̄ʒXk_}θθ}δ‚€ˆ} ̄.¡н}€θ

Ugh.. :/ Not the right language for the job.

Input as a list of lists.

Try it online or verify all test cases.

Explanation:

ε # For each list in the (implicit) input-list:
 R # Reverse the list
 ć # Extract its head; pop and push remainder-list and first item separated
 # to the stack
 Ð # Triplicate this value
 þ # Pop one copy, and only leave its digits
 Êi # If the top two copies are NOT the same (so it's not an integer):
 U # Pop and store the last copy in variable `X`
 ̄ # Push the global_array
 ʒ # Filter it by:
 Xk # Where the index of `X`
 _ # Is 0 (thus the key of the pair)
 }θ # After the filter: leave the last pair
 θ # Pop and leave its value
 } # Close the if-statement
 δ # For each value in the remainder-list:
 ‚ # Pair it with the top value
 € # Then for-each pair in this list:
 ˆ # Add this pair to the global_array
} ̄ # After the outer for-each: push the global_array
 .¡ # Group this list of pairs by:
 н # Its first value (the key)
 }€ # After the group-by: map over each group:
 θ # And only leave the last pair
 # (after which the top of the stack is output implicitly as result)
answered Sep 22, 2020 at 12:21
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 57 bytes

s/[a-z_]+/\$k{'$&'}/g;/=/&&eval}{say"$_=$k{$_}"for keys%k

Try it online!

answered Sep 22, 2020 at 16:28
\$\endgroup\$
1
\$\begingroup\$

R, 172 bytes

Takes input as a list of strings, returns a named vector. Just eval in R with aggressive escaping using the A character.

function(i){i=paste(gsub('([a-z_])', 'A\1円',i)[grepl('=',i)],collapse=';')
eval(parse(text=i))
rm("i")
u=ls()
x=sapply(u,function(name)get(name))
names(x)=gsub('A','',u)
x}

Try it online!

answered Sep 22, 2020 at 11:37
\$\endgroup\$
8
  • \$\begingroup\$ your answer needs to work even when keywords are used as names. function = 3 fails: Try it online! \$\endgroup\$ Commented Sep 22, 2020 at 11:45
  • \$\begingroup\$ since this isn't actually an answer, I'd recommend deleting it before it accumulates any downvotes. You can edit in the corrected version and undelete it later! Feel free to come talk to us in the R chatroom for help! I think using a list to store the name-value pairs will be a good approach, though :-) \$\endgroup\$ Commented Sep 22, 2020 at 14:32
  • \$\begingroup\$ Undeleted now! Still using the function's local environment. \$\endgroup\$ Commented Sep 22, 2020 at 16:31
  • \$\begingroup\$ Nice! A couple of things: parse is perfectly fine taking a text vector and it will evaluate each element in turn. text= can be shortened to t=. And you don't need to reassign i, you can use the gsub directly in the parse, down to 145 bytes! \$\endgroup\$ Commented Sep 22, 2020 at 16:58
  • \$\begingroup\$ I do know there's an answer less than 100 bytes so keep trying interesting golfs! :-) \$\endgroup\$ Commented Sep 22, 2020 at 17:01
1
\$\begingroup\$

Python 3, (削除) 69 (削除ここまで) 103 bytes

import re
def f(x):g={};exec(re.sub('(^|\n)[^=]+($|\n)','',x).upper(),{},g);return eval(str(g).lower())

Try it online!

+34 bytes to remove no-op lines in the input and avoid undefined variables

Takes advantage of the fact that no python keywords are uppercase, and variable names for this challenge will all be lowercase.

Saves several bytes thanks to a comment on my original (invalid) answer by @ovs:

Note that your original answer could have been 35 bytes with exec(x,{},g), since exec does not add builtins to the locals dictionary. (This is still invalid)

answered Sep 22, 2020 at 12:23
\$\endgroup\$
2
  • \$\begingroup\$ Like the ideas of the approach, but doesn't work for the def, 2, e = 8, 101 case, does it? \$\endgroup\$ Commented Sep 23, 2020 at 0:26
  • \$\begingroup\$ @Sisyphus Ah you're right, it fails for variables with no value. \$\endgroup\$ Commented Sep 23, 2020 at 12:01
1
\$\begingroup\$

Pip -rl, 57 bytes

{YDQaIx~'^.y.,wYXI~$'Fva.sxR:'^.v.,`.+|^$`v.y.n}Mg^sUQx^n

Try it online!

Takes input (from stdin) and produces output (to stdout) as a series of lines, each of the form a b c 5 (for a = b = c = 5). The output will have an extra blank line in it somewhere, which can be eliminated for +1 byte.

Pip is handicapped here by not having a dictionary/hashmap type. Our approach is to build the output as a string, using regex substitutions to update with new assignments. Further explanation available upon request, although I also hope to golf this more. Here's an earlier, pre-golfed version which may be easier to decipher.

answered Sep 25, 2020 at 4:28
\$\endgroup\$
1
\$\begingroup\$

Haskell, (削除) 177 (削除ここまで) (削除) 145 (削除ここまで) 141 bytes

r t=f(?)[](reverse.words.filter(/='=')<$>lines t)
s?(x:y)=f(#)s y where z|Just v<-lookup x s=v|1<2=read x;s#k=(k,z):[x|x<-s,fst x/=k]
f=foldl

Try it online!

Ungolfed:

run :: Read v => String -> [(String, v)]
run input = foldl assign [] (reverse . words . filter (/='=') <$> lines input)
assign :: Read v => [(String, v)] -> [String] -> [(String, v)]
assign scope (first:keys) = foldl acons scope keys
 where value | Just v <- lookup first scope = v
 | otherwise = read first
 acons scope' k = (k, value) : [x | x <- scope', fst x /= k]
answered Sep 25, 2020 at 11:23
\$\endgroup\$
2
  • \$\begingroup\$ I think you can replace your acons/# with (s#v)k=(k,v):[x|x<-s,fst x/=k]. \$\endgroup\$ Commented Sep 25, 2020 at 11:37
  • \$\begingroup\$ That is true. Doesn't maintain insertion order, but that's not a requirement anyway. \$\endgroup\$ Commented Sep 25, 2020 at 13:51
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 128 bytes

x=>{var z=new Dictionary<string,string>();x.ForEach(l=>{var s=l.Pop();l.Any(o=>(z[o]=z.ContainsKey(s)?z[s]:s)=="");});Print(z);}

Try it online!

answered Sep 24, 2020 at 18:18
\$\endgroup\$
0
\$\begingroup\$

PHP, 65 bytes

eval(preg_filter('/([a-z_]+)/','\$1ドル',$argn));var_dump($GLOBALS);

Try it online!

Takes input as string with ; as separator, outputs an array.

I'm not sure this is valid, as the rules for the output are not very precise: the result is present at the end, but there are other unnecessery things displayed before... For the first time PHP's $ comes useful, as it allows to use keywords as var names (works with names such as function, echo etc)

answered Oct 2, 2020 at 16:01
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.