Saturday, July 5, 2008

Knittin' Crap: I Am So Square

squaresblanketsquares I saw this pattern in the Spring 2006 issue of Interweave Crochet. I decided it looked really neat, but I didn't want to use the wool yarn shown. So I bought a bunch of different colors of Tahki Cotton Classic, which comes in 128 colors. (I only bought about 16). Since by this time the number of colors I had no longer matched the number in the pattern and my gauge would be totally different because the Cotton Classic is much heavier than the original yarn, I just decided to come up with a random list of my own colors.

Geek that I am, I made my computer do it.

I wrote a script in Perl that does the following:
  • Takes the list of color names (the array @colors)
  • Makes the specified number of each size (i.e. number of rows) square (the has %size_odds)
  • Always makes 2-row squares two different colors
  • In larger squares, increases the odds by 10% that the following row will use the same color as the row before it... I didn't want a bunch of 8-row squares in 8 different colors
  • Makes sure no two squares will be exactly the same
It outputs to two files. One uses the numbers assigned to each color by its position in the array @colors (only add to the end of this list if you add colors or it will get out of whack if you need to add more) and saves that to a file in case you need to add more squares later (that's a different script which, yes, I did have to write). The other produces the human-readable output, which looks like this:
1:orange 2:berry

1:candy pink 2:lime 3:lime 4:lime 5:sky blue 6:lilac

1:berry 2:lime sherbet 3:lime sherbet 4:lime sherbet 5:royal blue 6:lime 7:lime 8:canary 9:lilac 10:sky blue 11:navy 12:coral

1:candy pink 2:berry 3:sky blue 4:tangerine 5:green 6:dk pink

1:orange 2:navy

1:taupe 2:navy 3:navy 4:lime 

What it doesn't do: you can't specify the amounts of yarn you have by color and it doesn't compute the size of the blanket or conversely how many squares to make for a particular size.

I did actually run out of the lt. yellow, mainly because of that 12-row square in the picture where rows 7-12 were lt. yellow. It's probably not the last so far, so I wrote another script to replace it with other colors. I already have some partially made blocks that called for it.

Here's the script:
#!/usr/bin/perl

# blocks - make random colors for blocks for a blanket
# Karen B.

# Distributed under a Creative Commons Attribution-Share Alike 3.0 Unported License
# http://creativecommons.org/licenses/by-sa/3.0/

use strict;

my $namefile = "newblocks"; # Outfile - human-readable
my $savefile = "saveblocks"; # Outfile - numbers only

# Name your colors
my @colors = ( 'lime', 'sky blue', 'navy', 'candy pink', 'royal blue',
'dk pink', 'tomato', 'green', 'lilac', 'orange', 'coral',
'turquoise', 'jade', 'canary', 'lt. yellow', 'lime sherbet',
'taupe', 'tangerine', 'berry' );

# Number of rows => number of blocks in that size
my %size_odds = (
'2' => 50,
'4' => 49,
'6' => 16,
'8' => 7,
'10' => 2,
'12' => 2 );

my $cnum = $#colors + 1; # Actual number of colors

my %done;   # Hash of finished squares

foreach my $size (keys %size_odds) {
my $lim = $size_odds{$size};
while ($lim-- > 0) {
my $done;
my $out;

do {
 my %used;

 $out = '';
 my $round = 1;
 my $cur = int(rand($cnum));
 my $last = $cur;
 $done = "$cur";
 $out = "$round:$colors[$cur]";
 $used{$cur}++;
 $round++;
 if ($size == 2) {
   until ($last != $cur) {
     $cur = int(rand($cnum));
   }
   $out .= " $round:$colors[$cur]";
   $done .= ",$cur";
 } else {
   while ($round <= $size) {
     if (int(rand(3)) == 0) {
       $out .= " $round:$colors[$last]";
     } else {
       do {
         $cur = int(rand($cnum));
       } while ( $used{$cur} );
       $out .= " $round:$colors[$cur]";
       $used{$cur}++;
       $last = $cur;
     }
     $round++;
     $done .= ",$cur";
   }
  }
 } while ( exists($done{$done}) );
   $done{$done} = $out;
 }
}

open(OUT, ">$namefile");
print OUT join("\n\n", values %done); # This naturally "shuffles" the list
close(OUT);

open(COL, ">$savefile");
print COL join("\n", keys %done);
close(COL);

Creative Commons License This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.

1 comment:

Eri said...

love your geekiness!! awsome

Labels!