September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1 @@
--- {}

View file

@ -1,68 +1,76 @@
import system'routines.
import extensions.
import system'routines;
import extensions;
import extensions'text;
const Target = "METHINKS IT IS LIKE A WEASEL".
const AllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZ".
const string Target = "METHINKS IT IS LIKE A WEASEL";
const string AllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const C = 100.
const P = 0.05r.
const int C = 100;
const real P = 0.05r;
rnd = randomGenerator.
rnd = randomGenerator;
randomChar
= AllowedCharacters[rnd nextInt(AllowedCharacters length)].
= AllowedCharacters[rnd.nextInt(AllowedCharacters.Length)];
extension evoHelper
{
randomString
= 0 till:self repeat(:x)( randomChar ); summarize:(String new); literal.
randomString()
= 0.repeatTill(self).selectBy:(x => randomChar).summarize(new StringWriter());
fitnessOf:s
= self zip:s by(:a:b)( (a == b)iif(1,0) ); summarize(Integer new); int.
fitnessOf(s)
= self.zipBy(s, (a,b => a==b ? 1 : 0)).summarize(new Integer()).toInt();
mutate : p
= self selectBy(:ch)( (rnd nextReal <= p) iif(randomChar,ch) ); summarize(String new); literal.
mutate(p)
= self.selectBy:(ch => rnd.nextReal() <= p ? randomChar : ch).summarize(new StringWriter());
}
class EvoAlgorithm :: Enumerator
class EvoAlgorithm : Enumerator
{
object theTarget.
object theCurrent.
object theVariantCount.
object theTarget;
object theCurrent;
object theVariantCount;
constructor new : s of:count
[
theTarget := s.
theVariantCount := count int.
]
constructor new:of(s,count)
{
theTarget := s;
theVariantCount := count.toInt();
}
get = theCurrent.
get() = theCurrent;
next
[
if ($nil == theCurrent)
[ theCurrent := theTarget length; randomString. ^ true ].
bool next()
{
if (nil == theCurrent)
{ theCurrent := theTarget.Length.randomString(); ^ true };
if (theTarget == theCurrent)
[ ^ false ].
{ ^ false };
var variants := Array new:theVariantCount; populate(:x)( theCurrent mutate:P ).
auto variants := Array.allocate(theVariantCount).populate:(x => theCurrent.mutate:P );
theCurrent := variants array; sort(:a:b)( a fitnessOf:Target > b fitnessOf:Target ); getAt:0.
theCurrent := variants.sort:(a,b => a.fitnessOf:Target > b.fitnessOf:Target ).at:0;
^ true.
]
^ true
}
reset()
{
theCurrent := nil
}
enumerable() => theTarget;
}
program =
[
var attempt := Integer new.
EvoAlgorithm new:Target of:C; forEach(:current)
[
public program()
{
var attempt := new Integer();
EvoAlgorithm.new:Target of:C.forEach:(current)
{
console
printPaddingLeft(10,"#",attempt append:1);
printLine(" ",current," fitness: ",current fitnessOf:Target).
].
.printPaddingLeft(10,"#",attempt.append(1))
.printLine(" ",current," fitness: ",current.fitnessOf(Target))
};
console readChar.
].
console.readChar()
}

View file

@ -4,7 +4,7 @@ constant @alphabet = flat 'A'..'Z',' ';
constant C = 100;
sub mutate { [~] (rand < mutate_chance ?? @alphabet.pick !! $_ for $^string.comb) }
sub fitness { [+] $^string.comb Zeq state @ = target.comb }
sub fitness { [+] $^string.comb Zeq target.comb }
loop (
my $parent = @alphabet.roll(target.chars).join;

View file

@ -0,0 +1,55 @@
func evolve(
to target: String,
parent: inout String,
mutationRate: Int,
copies: Int
) {
var parentFitness: Int {
return fitness(target: target, sentence: parent)
}
var generation = 0
while parent != target {
generation += 1
let bestOfGeneration =
(0..<copies)
.map({_ in mutate(sentence: parent, rate: mutationRate) })
.map({ (fitness(target: target, sentence: $0), $0) })
.sorted(by: { $0.0 < $1.0 })
.first!
if bestOfGeneration.0 < parentFitness {
print("Gen \(generation) produced better fit. \(bestOfGeneration.1) with fitness \(bestOfGeneration.0)")
parent = bestOfGeneration.1
}
}
}
func fitness(target: String, sentence: String) -> Int {
return zip(target, sentence).filter(!=).count
}
func mutate(sentence: String, rate: Int) -> String {
return String(
sentence.map({char in
if Int.random(in: 1...100) - rate <= 0 {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZ ".randomElement()!
} else {
return char
}
})
)
}
let target = "METHINKS IT IS LIKE A WEASEL"
let copies = 100
let mutationRate = 20
var start = mutate(sentence: target, rate: 100)
print("target: \(target)")
print("Gen 0: \(start) with fitness \(fitness(target: target, sentence: start))")
evolve(to: target, parent: &start, mutationRate: mutationRate, copies: 100)