diff options
| -rw-r--r-- | challenge-034/colin-crain/perl5/ch-1.pl | 193 | ||||
| -rw-r--r-- | challenge-034/colin-crain/perl5/ch-2.pl | 130 | ||||
| -rw-r--r-- | stats/pwc-current.json | 299 | ||||
| -rw-r--r-- | stats/pwc-language-breakdown-summary.json | 66 | ||||
| -rw-r--r-- | stats/pwc-language-breakdown.json | 272 | ||||
| -rw-r--r-- | stats/pwc-leaders.json | 924 | ||||
| -rw-r--r-- | stats/pwc-summary-1-30.json | 116 | ||||
| -rw-r--r-- | stats/pwc-summary-121-150.json | 56 | ||||
| -rw-r--r-- | stats/pwc-summary-31-60.json | 32 | ||||
| -rw-r--r-- | stats/pwc-summary-61-90.json | 14 | ||||
| -rw-r--r-- | stats/pwc-summary-91-120.json | 26 | ||||
| -rw-r--r-- | stats/pwc-summary.json | 28 |
12 files changed, 1247 insertions, 909 deletions
diff --git a/challenge-034/colin-crain/perl5/ch-1.pl b/challenge-034/colin-crain/perl5/ch-1.pl new file mode 100644 index 0000000000..e20da1a037 --- /dev/null +++ b/challenge-034/colin-crain/perl5/ch-1.pl @@ -0,0 +1,193 @@ +#! /opt/local/bin/perl +# +# deli_slicer.pl +# +# PWC 34 - Task #1 +# Write a program that demonstrates using hash slices and/or array +# slices. +# +# In Perl, from the beginning, it has always been noted that "there is +# more than one way to do it". As such, I have seen through the years +# how programmers have a tendency to find their personal style -- tools +# and idioms that work for them -- and then apply them again and again +# to solve the specific problem of the moment. This is all well and +# good, but the fact of the matter is that whatever one is doing, +# there's probably a different way to go about it to get the job done. +# +# Hash slices allow accessing the values of subsets of keys for a hash, +# returning lists of results. As of 5.20 lists of alternating key value +# pairs can be returned, should you want that. In this mass translation +# of list data they much resemble the map function. Now I like lists, +# and working with list data operators like map and grep, so I can see +# the use of this. However one most interesting case I have found is using +# slices as lvalues, allowing bulk assignment to a hash in a nice +# succinct manner. For generated hashes this can be very quick, powerful +# and clean. +# +# So lets make a toy program. Say we want a to make a cypher, or a puzzle +# perhaps, based on assignment of numbers to letters. To make things +# interesting we'll assign a list of primes to letters, then we can take +# groups of letters and multiply them to produce a new number. After +# the fact we can reconstruct the letters that made up the original word +# by prime factorization. It's a toy, so we won't worry too much about +# why we might want to do such a thing, but it's neat. What we need is a +# hash, with letters of the alphabet mapped to sequential primes. +# +# From a previous challenge we constructed a prime number generator that +# produces a requested number of primes starting at 2. We'll take this +# subroutine and transplant it whole; it returns a list of primes on the +# stack. For our toy decoder, we will borrow two more prime-related +# subroutines: decompose(), which reduces a number into its prime +# factors, and its dependency make_primes(). +# +# We can now generate the required hash in one simple line: +# +# @hash{ ( 'a'..'z' ) } = make_primes(26); +# +# which is rather ridiculously easy. As part of an encoding function, we +# use another slice: +# +# @lookup{ split //, lc($word) } +# +# which takes the input phrase, chops it up into a list of letters, and +# returns a list of looked-up prime values for those component letters. +# In the decoding function we use a third slice: +# +# @reverse_lookup{ decompose($code_number) } +# +# which takes the list of primes returned by decompose() and produces a +# list of the corresponding letter values. +# +# So here we have three examples of the use of hash slices for list-wise +# data transformation, in this case each is fed not by a fixed list, but +# rather by a generated list returned by a function or subroutine; the +# slice syntax produces in turn a list of corresponding hash values. +# Displaying the transformation process shows the component letters of the +# words have lost their placement order but have been preserved. As the +# purpose here is to demonstrate the use of hash slices as list +# transformation tools, we'll leave it at that. Figuring out a way to save +# and reconstruct the letter order can be left as an exercise for the +# reader, or at least another time. +# +# +# 2019 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + + +use warnings; +use strict; +use feature ":5.26"; + +use List::Util qw(product); + +## ## ## ## ## MAIN + +my %lookup; + +## here we do bulk assignment to the hash from the list returned by a subroutine +@lookup{ ( 'a'..'z' ) } = make_primes(26); + +## output to demonstrate the key/value pairs produced +say "the generated lookup hash:\n"; +for (sort keys %lookup){ + printf "\t%s => %-d\n", $_, $lookup{$_}; +} + +## create a reverse_lookup lookup hash. We know the values are unique, being prime and all +my %reverse_lookup = reverse %lookup; + + +## toy test +my $phrase = 'The quick brown fox jumped over the lazy dog'; + +## first we encode the letters into primes and multiply them, using the List::Util::product function +my (@encoded, @decoded); +for my $word ( split /\s/, $phrase ) { + push @encoded, product( @lookup{ split //, lc($word) } ); +} +## then we decode the array of products back into their constituant letters +for my $code_number ( @encoded ) { + push @decoded, join '', ( @reverse_lookup{ decompose($code_number) }); +} + +## display the process +say ''; +printf " phrase: %s\n", $phrase; +printf "encoded: %s\n", (join " ", @encoded); +printf "decoded: %s\n", (join " ", @decoded); + + + +## ## ## ## ## SUBS + +sub make_primes { +## returns a list of as many primes as you ask it for + my $num_primes = shift; + my $count = 0; + my @output = (2); + my $is_prime; + for( my $candidate = 3; $count <= ($num_primes - 2); $candidate += 2 ) { + my $sqrt_candidate = sqrt( $candidate ); + $is_prime = 1; + for( my $test = 3; ( $test <= $sqrt_candidate ) && ( $is_prime==1 ); $test += 2 ) { + if( $candidate % $test == 0 ) { + $is_prime = 0; + } + } + if( $is_prime == 1 ) { + push @output, $candidate; + $count++; + } + } + return @output; +} + +sub decompose { +## given a number, +## returns an array list of prime decomposition factors of the number + my $num = shift; + my @decomp; + my $prime = 2; + my $primelist = [$prime]; + + while ( $prime <= $num ) { + while ($num % $prime == 0) { + $num = $num / $prime; + push @decomp, $prime; + } + $prime = get_next_prime($primelist); + } + return @decomp; + +} + +sub get_next_prime { + ## given a listref of all primes up until a certain point, + ## adds next prime to the list and returns the prime + + my $primelist = shift; + + ## assign the last prime recorded + 1 as the new candidate + my $candidate = $primelist->[scalar $primelist->@* - 1] + 1; + + ## index through the prime list checking for divisability; if found augment and restart the test. + ## if the test value exceeds the squareroot of the candidate, the candidate + ## is prime. Put it on the list and return the candidate. + ## yes it's an infinite loop but there will always be another prime, right? + ## ... + ## right? + for (my $i = 0; my $test = $primelist->[$i]; $i++) { + my $root = int(sqrt($candidate)); + if ($test > $root) { + push $primelist->@*, $candidate; + return $candidate; + } + + if ($candidate % $test == 0) { + $i = -1; + $candidate++; + next; + } + } +} diff --git a/challenge-034/colin-crain/perl5/ch-2.pl b/challenge-034/colin-crain/perl5/ch-2.pl new file mode 100644 index 0000000000..76c7875452 --- /dev/null +++ b/challenge-034/colin-crain/perl5/ch-2.pl @@ -0,0 +1,130 @@ +#! /opt/local/bin/perl +# +# dispatches.pl +# +# PWC 034 - Task #2 +# Write a program that demonstrates a dispatch table. +# +# in Perl, functions are first-class citizens, which means they can be +# indirectly referenced and those references assigned to variables just +# like any other data. These code references can be accessed using the +# arrow notation similarly to those employed with arrays and +# hashes, in this case giving the function a list of arguments: +# +# $function_reference->($arg1, $arg2, ...) +# +# In a dispatch table, the data is a collection of subroutine actions, +# gathered in another ubiqitous Perl data type, the hashtable. By +# looking up a given input against the keys of the the table, we obtain +# a selected action option as the value and can then execute the coderef. +# +# In this, the table resembles a C switch statement, selecting an action +# for the program's execution. With this functionality we can allow input +# data to alter the the program flow, at least within the possibilities +# defined in the subroutines. +# +# To demonstrate this, we'll build a little toy calculator. Inputting a +# string containing an expression, like +# +# ./dispatches.pl "2 * 3 + 5 / 4" +# +# evaluates the expression from left to right, switching the program +# execution and action on a running talley between mathematical operators +# as required. Each operator is defined by a subroutine keyed on the +# operator symbol, shifting its operands off an internal stack, held in +# the array reference $stack, and pushing the results back on as required. +# +# The input is given as a string to the program, which is then parsed +# into lists of operators and operands. The program can handle a string +# of any number of operations, but as this is a demonstration of a dispatch +# table for action on the stack array, the standard rules of operator +# precedence are not implemented and evaluation is strictly left to right +# without parentheses. +# +# As can be seen, the actual routines to process the mathematical +# operators are anonymous subroutines constructed within the hashtable +# definition itself. Note that division by zero is safe and does not +# crash the program, it simply returns 'NAN', for 'Not A Number'; the +# program then terminates without attempting to evaluate further. +# +# Implementation of an additional action is as simple as adding another +# key/value pair to the hash, as long as the input is correctly passed through +# preprocessing to match a key in the dispatch table. In this case a new +# operator can be most any string of non-word characters (the shell and +# Perl may cause problems when using '!', '$', and '@' -- be warned, as +# constructs containing these can produce unexpected results). I have +# inserted a new 'square of the difference' operator to demonstrate this. +# +# I have left in verbose code to examine the state of the program as it +# progresses; this makes it easy to see how the various operator actions +# change the stack, as the first elements are taken off and the result +# pushed back on as processing continues. A good example would be +# +# ./dispatches.pl "20 ** 2 * 0 - 35 *-* 5 / 4" +# +# which uses all of the possible operations, including the new "square of +# the difference" operator *-* that I just made up. +# +# 2109 colin crain +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + + + +#use warnings; +use strict; +use feature ":5.26"; + +## ## ## ## ## MAIN + +## first let us establish our dispatch table, and a few arrays to handle our lists of operators and operands +my $operator_dispatch = { + '*' => sub { my ($x, $y) = splice $_[0]->@*, 0, 2; ## multiply + unshift $_[0]->@*, ($x * $y) }, + '+' => sub { my ($x, $y) = splice $_[0]->@*, 0, 2; ## add + unshift $_[0]->@*, ($x + $y) }, + '-' => sub { my ($x, $y) = splice $_[0]->@*, 0, 2; ## subtract + unshift $_[0]->@*, ($x - $y) }, + '/' => sub { my ($x, $y, $result) = splice $_[0]->@*, 0, 2; ## divide (safe version) + eval {$result = $x/$y}; + ($@) and $result = 'NAN'; + unshift $_[0]->@*, $result}, + '**' => sub { my ($x, $y) = splice $_[0]->@*, 0, 2; ## power + unshift $_[0]->@*, ($x ** $y) }, + '*-*' => sub { my ($x, $y) = splice $_[0]->@*, 0, 2; ## 'square of the difference' new operator + unshift $_[0]->@*, (($x - $y)** 2) }, +}; + +my $stack = []; +my @operators; + +## fetch the input string and parse it +my @args = split /\s/, shift @ARGV; +say " exp: ", , (join " ", @args); + +for my $arg ( @args ) { + $arg =~ /^\d+$/ && push $stack->@*, $arg; + $arg =~ /^\W+$/ && push @operators, $arg; +} + +## iterate through the list of operators +for my $op ( @operators ) { + + ## we can chose to first check whether the key exists and do something if it doesn't + if (not exists $operator_dispatch->{$op}) { + exit { say "operator '$op' not recognized, cannot evaluate further" }; + } + + ## show us what's happening + say " stack: ", (join " ", $stack->@*); + say " op: ", $op; + + ## this one statement does all the heavy lifting for the calculator + $operator_dispatch->{$op}->($stack); + + ## once we are outside mathematics there is no point to continuing + last if $stack->[0] eq 'NAN'; +} + +# The running result will always be the first item on the stack, so when we run +# out of operators that's what we have left +say "result: $stack->[0]"; diff --git a/stats/pwc-current.json b/stats/pwc-current.json index b022ef5d38..9b5b1e0681 100644 --- a/stats/pwc-current.json +++ b/stats/pwc-current.json @@ -1,122 +1,18 @@ { - "plotOptions" : { - "series" : { - "borderWidth" : 0, - "dataLabels" : { - "enabled" : 1, - "format" : "{point.y}" - } - } - }, - "chart" : { - "type" : "column" - }, - "tooltip" : { - "followPointer" : 1, - "headerFormat" : "<span style='font-size:11px'>{series.name}</span><br/>", - "pointFormat" : "<span style='color:{point.color}'>{point.name}</span>: <b>{point.y:f}</b><br/>" - }, - "series" : [ - { - "name" : "Perl Weekly Challenge - 034", - "colorByPoint" : 1, - "data" : [ - { - "name" : "Andrezgz", - "y" : 2, - "drilldown" : "Andrezgz" - }, - { - "y" : 3, - "drilldown" : "Arne Sommer", - "name" : "Arne Sommer" - }, - { - "name" : "Dave Cross", - "y" : 2, - "drilldown" : "Dave Cross" - }, - { - "drilldown" : "Duane Powell", - "y" : 2, - "name" : "Duane Powell" - }, - { - "name" : "E. Choroba", - "y" : 2, - "drilldown" : "E. Choroba" - }, - { - "name" : "Javier Luque", - "drilldown" : "Javier Luque", - "y" : 5 - }, - { - "name" : "Kevin Colyer", - "drilldown" : "Kevin Colyer", - "y" : 2 - }, - { - "name" : "Laurent Rosenfeld", - "drilldown" : "Laurent Rosenfeld", - "y" : 5 - }, - { - "name" : "Mark Anderson", - "y" : 1, - "drilldown" : "Mark Anderson" - }, - { - "y" : 2, - "drilldown" : "Noud", - "name" : "Noud" - }, - { - "name" : "Petr Roubicek", - "y" : 1, - "drilldown" : "Petr Roubicek" - }, - { - "name" : "Roger Bell West", - "y" : 4, - "drilldown" : "Roger Bell West" - }, - { - "name" : "Ruben Westerberg", - "y" : 4, - "drilldown" : "Ruben Westerberg" - }, - { - "name" : "Simon Proctor", - "drilldown" : "Simon Proctor", - "y" : 2 - }, - { - "drilldown" : "Steven Wilson", - "y" : 3, - "name" : "Steven Wilson" - }, - { - "name" : "Ulrich Rieke", - "drilldown" : "Ulrich Rieke", - "y" : 2 - } - ] - } - ], "drilldown" : { "series" : [ { + "id" : "Andrezgz", "data" : [ [ "Perl 5", 2 ] ], - "id" : "Andrezgz", "name" : "Andrezgz" }, { + "id" : "Arne Sommer", "data" : [ [ "Perl 6", @@ -127,28 +23,37 @@ 1 ] ], - "id" : "Arne Sommer", "name" : "Arne Sommer" }, { - "name" : "Dave Cross", - "id" : "Dave Cross", + "id" : "Colin Crain", "data" : [ [ "Perl 5", 2 ] - ] + ], + "name" : "Colin Crain" + }, + { + "data" : [ + [ + "Perl 5", + 2 + ] + ], + "id" : "Dave Cross", + "name" : "Dave Cross" }, { - "name" : "Duane Powell", "id" : "Duane Powell", "data" : [ [ "Perl 5", 2 ] - ] + ], + "name" : "Duane Powell" }, { "data" : [ @@ -161,6 +66,7 @@ "name" : "E. Choroba" }, { + "id" : "Javier Luque", "data" : [ [ "Perl 5", @@ -175,20 +81,20 @@ 1 ] ], - "id" : "Javier Luque", "name" : "Javier Luque" }, { - "name" : "Kevin Colyer", "id" : "Kevin Colyer", "data" : [ [ "Perl 6", 2 ] - ] + ], + "name" : "Kevin Colyer" }, { + "name" : "Laurent Rosenfeld", "data" : [ [ "Perl 5", @@ -203,40 +109,41 @@ 1 ] ], - "id" : "Laurent Rosenfeld", - "name" : "Laurent Rosenfeld" + "id" : "Laurent Rosenfeld" }, { "id" : "Mark Anderson", - "name" : "Mark Anderson", "data" : [ [ "Perl 5", 1 ] - ] + ], + "name" : "Mark Anderson" }, { - "name" : "Noud", - "id" : "Noud", "data" : [ [ "Perl 6", 2 ] - ] + ], + "id" : "Noud", + "name" : "Noud" }, { - "id" : "Petr Roubicek", - "name" : "Petr Roubicek", "data" : [ [ "Perl 5", 1 ] - ] + ], + "id" : "Petr Roubicek", + "name" : "Petr Roubicek" }, { + "name" : "Roger Bell West", + "id" : "Roger Bell West", "data" : [ [ "Perl 5", @@ -246,13 +153,11 @@ "Perl 6", 2 ] - ], - "id" : "Roger Bell West", - "name" : "Roger Bell West" + ] }, { - "id" : "Ruben Westerberg", "name" : "Ruben Westerberg", + "id" : "Ruben Westerberg", "data" : [ [ "Perl 5", @@ -265,17 +170,16 @@ ] }, { + "name" : "Simon Proctor", + "id" : "Simon Proctor", "data" : [ [ "Perl 6", 2 ] - ], - "id" : "Simon Proctor", - "name" : "Simon Proctor" + ] }, { - "id" : "Steven Wilson", "name" : "Steven Wilson", "data" : [ [ @@ -286,35 +190,146 @@ "Perl 6", 1 ] - ] + ], + "id" : "Steven Wilson" }, { - "name" : "Ulrich Rieke", "id" : "Ulrich Rieke", "data" : [ [ "Perl 6", 2 ] - ] + ], + "name" : "Ulrich Rieke" } ] }, + "legend" : { + "enabled" : 0 + }, + "plotOptions" : { + "series" : { + "borderWidth" : 0, + "dataLabels" : { + "enabled" : 1, + "format" : "{point.y}" + } + } + }, + "tooltip" : { + "pointFormat" : "<span style='color:{point.color}'>{point.name}</span>: <b>{point.y:f}</b><br/>", + "followPointer" : 1, + "headerFormat" : "<span style='font-size:11px'>{series.name}</span><br/>" + }, "yAxis" : { "title" : { "text" : "Total Solutions" } }, - "subtitle" : { - "text" : "[Champions: 16] Last updated at 2019-11-17 19:34:57 GMT" + "xAxis" : { + "type" : "category" }, "title" : { "text" : "Perl Weekly Challenge - 034" }, - "legend" : { - "enabled" : 0 + "series" : [ + { + "name" : "Perl Weekly Challenge - 034", + "colorByPoint" : 1, + "data" : [ + { + "name" : "Andrezgz", + "drilldown" : "Andrezgz", + "y" : 2 + }, + { + "drilldown" : "Arne Sommer", + "name" : "Arne Sommer", + "y" : 3 + }, + { + "y" : 2, + "drilldown" : "Colin Crain", + "name" : "Colin Crain" + }, + { + "y" : 2, + "drilldown" : "Dave Cross", + "name" : "Dave Cross" + }, + { + "y" : 2, + "name" : "Duane Powell", + "drilldown" : "Duane Powell" + }, + { + "y" : 2, + "drilldown" : "E. Choroba", + "name" : "E. Choroba" + }, + { + "y" : 5, + "name" : "Javier Luque", + "drilldown" : "Javier Luque" + }, + { + "name" : "Kevin Colyer", + "drilldown" : "Kevin Colyer", + "y" : 2 + }, + { + "drilldown" : "Laurent Rosenfeld", + "name" : "Laurent Rosenfeld", + "y" : 5 + }, + { + "name" : "Mark Anderson", + "drilldown" : "Mark Anderson", + "y" : 1 + }, + { + "y" : 2, + "drilldown" : "Noud", + "name" : "Noud" + }, + { + "name" : "Petr Roubicek", + "drilldown" : "Petr Roubicek", + "y" : 1 + }, + { + "drilldown" : "Roger Bell West", + "name" : "Roger Bell West", + "y" : 4 + }, + { + "drilldown" : "Ruben Westerberg", + "name" : "Ruben Westerberg", + "y" : 4 + }, + { + "name" : "Simon Proctor", + "drilldown" : "Simon Proctor", + "y" : 2 + }, + { + "drilldown" : "Steven Wilson", + "name" : "Steven Wilson", + "y" : 3 + }, + { + "name" : "Ulrich Rieke", + "drilldown" : "Ulrich Rieke", + "y" : 2 + } + ] + } + ], + "subtitle" : { + "text" : "[Champions: 17] Last updated at 2019-11-17 21:21:28 GMT" }, - "xAxis" : { - "type" : "category" + "chart" : { + "type" : "column" } } diff --git a/stats/pwc-language-breakdown-summary.json b/stats/pwc-language-breakdown-summary.json index 7233d6b9b9..97bd53fd18 100644 --- a/stats/pwc-language-breakdown-summary.json +++ b/stats/pwc-language-breakdown-summary.json @@ -1,25 +1,6 @@ { - "title" : { - "text" : "Perl Weekly Challenge Contributions - 2019" - }, - "chart" : { - "type" : "column" - }, "series" : [ { - "name" : "Contributions", - "dataLabels" : { - "color" : "#FFFFFF", - "y" : 10, - "enabled" : "true", - "rotation" : -90, - "style" : { - "fontSize" : "13px", - "fontFamily" : "Verdana, sans-serif" - }, - "format" : "{point.y:.0f}", - "align" : "right" - }, "data" : [ [ "Blog", @@ -27,37 +8,56 @@ ], [ "Perl 5", - 1443 + 1445 ], [ "Perl 6", 858 ] - ] + ], + "name" : "Contributions", + "dataLabels" : { + "style" : { + "fontSize" : "13px", + "fontFamily" : "Verdana, sans-serif" + }, + "y" : 10, + "align" : "right", + "rotation" : -90, + "enabled" : "true", + "format" : "{point.y:.0f}", + "color" : "#FFFFFF" + } } ], + "chart" : { + "type" : "column" + }, + "subtitle" : { + "text" : "Last updated at 2019-11-17 21:21:36 GMT" + }, "legend" : { "enabled" : "false" }, - "yAxis" : { - "title" : { - "text" : null - }, - "min" : 0 - }, - "subtitle" : { - "text" : "Last updated at 2019-11-17 19:35:05 GMT" + "tooltip" : { + "pointFormat" : "<b>{point.y:.0f}</b>" }, "xAxis" : { "labels" : { "style" : { - "fontSize" : "13px", - "fontFamily" : "Verdana, sans-serif" + "fontFamily" : "Verdana, sans-serif", + "fontSize" : "13px" } }, "type" : "category" }, - "tooltip" : { - "pointFormat" : "<b>{point.y:.0f}</b>" + "yAxis" : { + "min" : 0, + "title" : { + "text" : null + } + }, + "title" : { + "text" : "Perl Weekly Challenge Contributions - 2019" } } diff --git a/stats/pwc-language-breakdown.json b/stats/pwc-language-breakdown.json index cadc7e9a0f..9c56d3bdd7 100644 --- a/stats/pwc-language-breakdown.json +++ b/stats/pwc-language-breakdown.json @@ -1,29 +1,4 @@ { - "legend" : { - "enabled" : "false" - }, - "yAxis" : { - "title" : { - "text" : "Total Solutions" - } - }, - "tooltip" : { - "headerFormat" : "<span style=\"font-size:11px\"></span>", - "pointFormat" : "<span style=\"color:{point.color}\">Challenge {point.name}</span>: <b>{point.y:f}</b><br/>", - "followPointer" : "true" - }, - "xAxis" : { - "type" : "category" - }, - "subtitle" : { - "text" : "Click the columns to drilldown the language breakdown. Last updated at 2019-11-17 19:35:06 GMT" - }, - "chart" : { - "type" : "column" - }, - "title" : { - "text" : "Perl Weekly Challenge Language" - }, "plotOptions" : { "series" : { "dataLabels" : { @@ -33,11 +8,17 @@ "borderWidth" : 0 } }, + "yAxis" : { + "title" : { + "text" : "Total Solutions" + } + }, + "title" : { + "text" : "Perl Weekly Challenge Language" + }, "drilldown" : { "series" : [ { - "id" : "001", - "name" : "001", "data" : [ [ "Perl 5", @@ -51,10 +32,11 @@ "Blog", 11 ] - ] + ], + "name" : "001", + "id" : "001" }, { - "name" : "002", "id" : "002", "data" : [ [ @@ -69,9 +51,12 @@ "Blog", 9 ] - ] + ], + "name" : "002" }, { + "id" : "003", + "name" : "003", "data" : [ [ "Perl 5", @@ -85,12 +70,9 @@ "Blog", 9 ] - ], - "id" : "003", - "name" : "003" + ] }, { - "name" : "004", "id" : "004", "data" : [ [ @@ -105,11 +87,11 @@ "Blog", 10 ] - ] + ], + "name" : "004" }, { "name" : "005", - "id" : "005", "data" : [ [ "Perl 5", @@ -123,9 +105,12 @@ "Blog", 11 ] - ] + ], + "id" : "005" }, { + "id" : "006", + "name" : "006", "data" : [ [ "Perl 5", @@ -139,9 +124,7 @@ "Blog", 7 ] - ], - "name" : "006", - "id" : "006" + ] }, { "data" : [ @@ -162,8 +145,6 @@ "id" : "007" }, { - "id" : "008", - "name" : "008", "data" : [ [ "Perl 5", @@ -177,9 +158,12 @@ "Blog", 12 ] - ] + ], + "name" : "008", + "id" : "008" }, { + "id" : "009", "data" : [ [ "Perl 5", @@ -194,10 +178,10 @@ 13 ] ], - "id" : "009", "name" : "009" }, { + "name" : "010", "data |
