previndexinfonext

code guessing, round #50 (completed)

started at ; stage 2 at ; ended at

specification

yawn. I'm tired. the problem today is to implement autocomplete--

oh? what's this? coltrans already wrote the spec for me. how convenient! ^C ^V...

It's none other than round fifty, a round number, and if I'm not in Err, a quarter quell! 'Course, round twenty-five hadn't any especial attention but I digress. It's time to get with the times. We live in the future, a world of AI and computers. Your challenge, an ye deign to rise to meet it, is to implement machine learning text autocomplete.

Now, allow me to produce this envelope with a flourish, and reveal that extra quarterly sauce: all tributes will be democratically elected for a change— whoops, wrong envelope, let me light that one on fire. No, the true trick is, only languages released over 25 years ago are permitted — as a reminder to would-be rebels that change is bad (and an encore for has-been languages so that we learn from the past).

You may choose one of the following APIs:

'Machine learning' includes techniques like Markov chains. The corpus parameter has text available to help train your machine learning autocomplete. You can expect train to be called exactly once. Your complete function may produce any amount of output, although the result should depend on text_so_far given some corpus.

hi, me again. coltrans pretty much covered everything, but I'd like to clarify something about the allowed languages. the age requirement only applies to the language, not the particular version you're using. that means that you can use python 3.12, even though it's brand new, because python 1 is from 1991. ok?

results

  1. 👑 LyricLy +4 -1 = 3
    1. taswelll
    2. olus2000
    3. Dolphy
    4. luatic
  2. taswelll +2 -2 = 0
    1. LyricLy (was olus2000)
    2. olus2000 (was LyricLy)
    3. Dolphy
    4. luatic
  3. olus2000 +1 -1 = 0
    1. taswelll
    2. luatic (was LyricLy)
    3. LyricLy (was Dolphy)
    4. Dolphy (was luatic)
  4. Dolphy +2 -3 = -1
    1. olus2000 (was taswelll)
    2. taswelll (was olus2000)
    3. LyricLy
    4. luatic
  5. luatic +1 -3 = -2
    1. LyricLy (was taswelll)
    2. taswelll (was olus2000)
    3. olus2000 (was LyricLy)
    4. Dolphy

entries

you can download all the entries

entry #1

written by taswelll
submitted at
0 likes

guesses
comments 0

post a comment


markov.k ASCII text
1
2
or:5;d:z!z:,"";{d[l]:d[l:-1_x],*|x;}',/or((-!or-1)_\:)':1:"input.txt";
`prng 0;`0:999{x,a@*1?#a:(.d)@*(^:)_(!d)?(!1+#a)_\:a:((#x)-or-1)_x}/*x

entry #2

written by olus2000
submitted at
0 likes

guesses
comments 1
taswelll

works for all ⎕io entry←⊃((125⊥,)/⎕AV⍳⊢)⌽⊣


post a comment


entry.apl Unicode text, UTF-8 text
1
2
3
⍝ Takes corpus on the left and text_so_far on the right.
⍝ Produces the next expected character.
entry(⊣⊃1+(⍴⊣)|((⊢+125×⊣)/⎕AV⍳⊢))

entry #3

written by LyricLy
submitted at
0 likes

guesses
comments 0

post a comment


a.py ASCII text
1
2
3
4
5
def complete(corpus, text_so_far):
    if text_so_far in corpus:
        return corpus.split(text_so_far, 1)[1].split(maxsplit=1)[0]
    else:
        return complete(corpus, text_so_far.split(maxsplit=1)[1])

entry #4

written by Dolphy
submitted at
0 likes

guesses
comments 0

post a comment


trans_rights_are_human_rights.cpp ASCII text
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <random>
#include <string>
#include <unordered_map>
#include <vector>

// A markov state contains words with their weights
typedef std::unordered_map<std::string, std::size_t> MarkovState;
typedef std::unordered_map<std::string, MarkovState> MarkovChain;
MarkovChain markovChain;

std::vector<std::string> split_str(const std::string& str, const std::string& delim)
{
    std::size_t current_pos = 0;
    std::size_t prev_pos = 0;
    std::vector<std::string> result{};

    while((current_pos = str.find(delim, prev_pos)) != std::string::npos)
    {
        result.push_back(str.substr(prev_pos, current_pos - prev_pos));
        prev_pos = current_pos + delim.size();
    }

    result.push_back(str.substr(prev_pos, current_pos));
    return result;
}

std::string get_next_word(const std::string& last_word)
{
    if(markovChain.count(last_word) == 0)
    {
        return "";
    }

    // Weighted random shit
    static std::random_device dev;
    static std::mt19937 rng(dev());

    std::size_t total_weight = 0;
    for(auto&[word, weight] : markovChain[last_word])
    {
        total_weight += weight;
    }

    std::uniform_int_distribution<std::size_t> dist(0, total_weight - 1);
    std::size_t random_weight = dist(rng);

    std::size_t sum = 0;
    for(auto&[word, weight] : markovChain[last_word])
    {
        if(sum <= random_weight && random_weight < sum + weight)
        {
            return word;
        }
        sum += weight;
    }

    return "";
}

void train(const std::string& corpus)
{
    std::vector<std::string> splitted_corpus = split_str(corpus, " ");
    // Build Markov chain
    for(std::size_t i = 0; i < splitted_corpus.size() - 1; ++i)
    {
        std::string& current_word = splitted_corpus[i];
        std::string& next_word = splitted_corpus[i + 1];

        markovChain[current_word][next_word]++;
    }
}

std::string complete(const std::string& text_so_far, std::size_t len=1)
{
    auto v = split_str(text_so_far, " ");
    std::string last_word = v[v.size() - 1];
    std::string result{};

    while(len--)
    {
        std::string next_word = get_next_word(last_word);
        if(next_word.empty())
        {
            return result;
        }
        
        result += (next_word + " ");
        last_word = next_word;
    }

    return result;
}

int main()
{
    std::string training_text{};
    std::string text_so_far{};

    std::cout << "Enter training text: ";
    std::getline(std::cin, training_text);
    std::cout << "Enter text so far: ";
    std::getline(std::cin, text_so_far);

    train(training_text);
    std::cout << complete(text_so_far, 99) << std::endl;

    return 0;
}

entry #5

written by luatic
submitted at
0 likes

guesses
comments 0

post a comment


thing.java ASCII text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.util.*;import java.util.regex.Pattern;import java.util.stream.*;import java.io.*;
// da spek sed "Your complete function may produce any amount of output, although the result should depend on text_so_far given some corpus."
// dis meks a infinte strem o'. do smth liek java thing.java "I like fish" <bible.txt | head -c 1000 o jst ctrl^C idk
class Thing{
public static void main(String... args){
final var corpus=new BufferedReader(new InputStreamReader(System.in)).lines().collect(Collectors.joining("\n"));
final var text_so_far=args[0];
final var n=3;
var next=new HashMap<String,ArrayList<String>>();
var p=Pattern.compile("\\w+");
var m=p.matcher(corpus);
var prevs=new ArrayList<String>();
prevs.add("");
while(m.find()){
var tok=m.group();
var ctx=prevs.get(prevs.size()-1);
for(var i=1;i<=Math.min(prevs.size()-1,n);i++){
var nexts=next.getOrDefault(ctx,new ArrayList<>());
nexts.add(tok);
next.put(ctx,nexts);
ctx=" "+prevs.get(prevs.size()-1-i)+" "+ctx;
}
prevs.add(tok);
}
var r=new Random();
m=p.matcher(text_so_far);
var ks=prevs;
prevs=new ArrayList<String>();
for (var i=0;i<n;i++)
prevs.add(ks.get(r.nextInt(ks.size())));
while (m.find())
prevs.add(m.group());
while(true){
var ctx = prevs.get(prevs.size()-1);
var choisez = new ArrayList<String>();
for(var j=1;j<=Math.min(prevs.size()-1,n);j++) {
choisez.addAll(next.getOrDefault(ctx, new ArrayList<>()));
ctx = prevs.get(prevs.size()-1-j)+" "+ctx;
}
if(choisez.isEmpty()){
for(var i=0;i<n;i++)
prevs.add(ks.get(r.nextInt(ks.size())));
}
var w = choisez.get(r.nextInt(choisez.size()));
System.out.print(" "+w);
prevs.add(w);
}
}
}