Skip to content

Instantly share code, notes, and snippets.

@MarcPer
Created February 6, 2022 19:43
Show Gist options
  • Save MarcPer/130904256430bacca679c4054cfb3a5c to your computer and use it in GitHub Desktop.
Save MarcPer/130904256430bacca679c4054cfb3a5c to your computer and use it in GitHub Desktop.
Wordle with segfault
def parse_vec file
v = {}
file.split("\n").each do |s|
arr = s.split(":")
v[arr[0]] = arr[1].gsub("[", "").gsub("]", "").split(",").map(&:to_i)
end
v
end
def parse_inv file
v = {}
file.split("\n").each do |s|
arr = s.split(":")
v[arr[0]] = arr[1].gsub("{", "").gsub("}", "").split(", ").map do |st| st.gsub("'", '') end
end
v
end
def parse_tweets file
d = {}
file.split("\r\n").each do |ln|
parts = ln.split ";"
day = parts[0].to_i
id = parts[1]
guesses = parts[2]
.gsub("[", "").gsub("]", "")
.split(", ").map {|st| st.gsub("'", '')}
d[day] ||= {}
d[day][id] = guesses
end
d
end
def cosine_slow(v1, v2)
dot_product = 0
v1.zip(v2).each do |v1i, v2i|
dot_product += v1i * v2i
end
a = v1.map { |n| n ** 2 }.reduce(:+)
b = v2.map { |n| n ** 2 }.reduce(:+)
return dot_product / (Math.sqrt(a) * Math.sqrt(b))
end
def cosine_fast(v1, v2)
dot_product = 0
a = 0
b = 0
v1.size.times do |i|
dot_product += v1[i] * v2[i]
a += v1[i]**2
b += v2[i]**2
end
return dot_product / (Math.sqrt(a) * Math.sqrt(b))
end
def cosine(v1, v2)
cosine_fast(v1, v2)
end
def counter list
counts = {}
for l in list do
counts[l] ||= 0
counts[l] = counts[l] +1
end
counts
end
def evaluate_guess(answer, guess)
res = ['','','','','']
matches = {}
gue_c = guess.chars
ans_c = answer.chars
ans_letters = counter(ans_c)
gue_c.each {|c| matches[c] = 0}
gue_c.each_with_index do |c, i|
if answer[i]==c
res[i] = 'Y'
matches[c] += 1
end
end
gue_c.each_with_index do |c, i|
if res[i] != 'Y'
if ans_c.include? c && matches[c] < (ans_letters[c] || 0)
res[i] = 'M'
mathces[c] += 1
else res[i] = 'N'
end
end
end
res
end
def read_data(args, filename, small=false)
folder = small ? "data/small/" : "data/"
args.gtk.read_file(File.join(folder, filename))
end
def tick args
args.state.results ||= {}
small = false
if args.state.results.empty?
letters = ['Y', 'M', 'N']
vec_locs = letters.product(letters).product(letters).product(letters).product(letters)
.map {|arr| arr.flatten.join('') }.sort
args.state.v_all ||= parse_vec(read_data(args, "vec_all.txt", small))
args.state.v_ratio ||= parse_vec(read_data(args, "vec_ratio.txt", small))
args.state.answers ||= read_data(args, "answers.txt", small).split('\n')
args.state.other_words ||= read_data(args, "other_words.txt", small).split('\n')
args.state.invalid_results ||= parse_inv(read_data(args, "invalid_results.txt", small))
args.state.tweets ||= parse_tweets(read_data(args, "tweets.txt", small))
# args.state.tweets.each do |day, games|
# if day != 210 { next }
day = 210
games = args.state.tweets[day]
all_counts = counter(games.find_all {|g| g.length > 1 && g[-1] == 'YYYYY'}.flatten )
first_counts = counter(games.find_all {|g| g.length > 1 && g[-1] == 'YYYYY'}.map {|g| g[0]})
penultimate_counts = counter(games.find_all {|g| g.length > 1 && g[-1] == 'YYYYY'}.map {|g| g[-2]})
vec_all = vec_locs.map {|res| all_counts[res] || 0}
# puts vec_all.size
# puts "Num words: #{args.state.v_all.keys.size}"
# puts "Games: #{games.size}"
vec_first = vec_locs.map {|res| first_counts[res] || 0}
vec_penultimate = vec_locs.map {|res| penultimate_counts[res] || 0}
vec_ratio = vec_locs.map {|res| (penultimate_counts[res] || 0)/((all_counts[res] || 0)+1e-6)}
# args.state.results = [1]
# return
dists = {"all" => {}, "ratio" => {}, "invalid" => {}}
args.state.v_all.each_key do |word|
dists["all"][word] = cosine(vec_all, args.state.v_all[word])
dists["ratio"][word] = cosine(vec_ratio, args.state.v_ratio[word])
invalid_res = args.state.invalid_results[word]
dists["invalid"][word] = games.count {|g| invalid_res.any? { |w| g.include?(w) } }
# dists["invalid"][word] = games.count {|g| !(g & args.state.invalid_results[word]).empty? }
end
ranks = {}
dists.each do |type, value|
s = value.sort_by{|k, v| v}
ranks[type] = {}
s.length.times {|i| ranks[type][s[i][0]] = i}
end
overall = {}
args.state.v_all.each_key do |key|
overall[key] = ranks.map {|k, v| v[key]}
end
overall_s = overall.sort_by {|k, v| v}
my_guess = overall_s[0][0]
answer = args.state.answers[day]
answer_rank = overall_s.map {|a| a[0]}.index(answer)
# results.insert([i, my_guess, answer, answer_rank, overall, dists, ranks])
feedback = evaluate_guess(answer.to_s, my_guess.to_s).join
if answer==my_guess
feedback.concat(" !!!!!!")
else
feedback.concat(" :(:( the actual answer was #{answer}, which ranked #{answer_rank} on my guess list")
end
# puts("For Wordle #{day}, my guess was #{my_guess}. #{feedback}")
args.state.results[day] = my_guess
end
# end
args.outputs.labels << [640, 500, args.state.results, 5, 1]
end
def log_perf(args, name, &bl)
now = Time.now.to_i
args.gtk.append_file_root("perf.log", "started #{name}\n")
bl.call
args.gtk.append_file_root("perf.log", "done #{name} in #{Time.now.to_i - now}\n")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment