diff --git a/README.md b/README.md index fbe27f5..e900774 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ My (attempted) solutions to [Advent of Code 2020](https://adventofcode.com/2020) in Elixir. -image +image ## Strategy diff --git a/day16/README b/day16/README new file mode 100644 index 0000000..9f18249 --- /dev/null +++ b/day16/README @@ -0,0 +1,56 @@ +Day 16 Notes + ++--------+ +| Part 1 | ++--------+ + +$ elixir day16part1.exs +28884 + +Thoughts: + + ++--------+ +| Part 2 | ++--------+ + +$ elixir day16part2.exs +Idenfitied columns: %{ + "arrival location" => 18, + "arrival platform" => 12, + "arrival station" => 10, + "arrival track" => 7, + "class" => 15, + "departure date" => 11, + "departure location" => 2, + "departure platform" => 13, + "departure station" => 14, + "departure time" => 1, + "departure track" => 9, + "duration" => 0, + "price" => 5, + "route" => 16, + "row" => 19, + "seat" => 17, + "train" => 4, + "type" => 3, + "wagon" => 6, + "zone" => 8 +} +Answer: 1001849322119 + +Thoughts: + + ++------------------+ +| Overall Thoughts | ++------------------+ + +Initial version. Will tidy up later. + +Spent a bit too long on silly mistakes in this one. Think I need to consider my development +process to help avoid making errors. + +Also, I'm finding these daily puzzles a bit too distracting from work. I think after today +I'm going to relegate them to the weekend. Doing them in the evenings has too much potential +to spill over into the next day. diff --git a/day16/day16part1.exs b/day16/day16part1.exs new file mode 100644 index 0000000..5b2104e --- /dev/null +++ b/day16/day16part1.exs @@ -0,0 +1,42 @@ +defmodule Day16Part1 do + def run do + {rules, _my_ticket, tickets} = + File.read!("input") + |> parse_input() + + Enum.flat_map(tickets, &invalid_fields(&1, rules)) + |> Enum.sum() + |> IO.puts() + end + + def parse_input(input) do + [rules, [_, my_ticket | _], [_ | nearby_tickets]] = + input + |> String.split("\n\n", trim: true) + |> Enum.map(&String.split(&1, "\n", trim: true)) + + rules = Enum.map(rules, &parse_rule/1) + + [my_ticket | nearby_tickets] = + [my_ticket | nearby_tickets] + |> Enum.map(fn ticket -> String.split(ticket, ",") |> Enum.map(&String.to_integer/1) end) + + {rules, my_ticket, nearby_tickets} + end + + def parse_rule(rule) do + [name | ranges] = + Regex.run(~r/\A(.*): (\d+)-(\d+) or (\d+)-(\d+)\z/, rule, capture: :all_but_first) + + [a, b, c, d] = Enum.map(ranges, &String.to_integer/1) + {name, a..b, c..d} + end + + def invalid_fields(ticket, rules) do + Enum.reject(ticket, fn field -> + Enum.any?(rules, fn {_name, range1, range2} -> field in range1 || field in range2 end) + end) + end +end + +Day16Part1.run() diff --git a/day16/day16part2.exs b/day16/day16part2.exs new file mode 100644 index 0000000..eb354bb --- /dev/null +++ b/day16/day16part2.exs @@ -0,0 +1,95 @@ +defmodule Day16Part2 do + def run do + {rules, my_ticket, tickets} = + File.read!("input") + |> parse_input() + + tickets + |> Enum.filter(&valid?(&1, rules)) + |> transpose_tickets() + |> identify_columns(rules) + |> IO.inspect(label: "Idenfitied columns", charlists: :as_lists) + |> Enum.filter(&match?({"departure" <> _, _idx}, &1)) + |> Enum.reduce(1, fn {_name, idx}, acc -> my_ticket[idx] * acc end) + |> IO.inspect(label: "Answer") + end + + def parse_input(input) do + [rules, [_, my_ticket | _], [_ | nearby_tickets]] = + input + |> String.split("\n\n", trim: true) + |> Enum.map(&String.split(&1, "\n", trim: true)) + + rules = Map.new(rules, &parse_rule/1) + + [my_ticket | nearby_tickets] = + [my_ticket | nearby_tickets] + |> Enum.map(fn ticket -> String.split(ticket, ",") |> Enum.map(&String.to_integer/1) end) + + my_ticket = my_ticket |> Enum.with_index() |> Map.new(fn {val, idx} -> {idx, val} end) + + {rules, my_ticket, nearby_tickets} + end + + def parse_rule(rule) do + [name | ranges] = + Regex.run(~r/\A(.*): (\d+)-(\d+) or (\d+)-(\d+)\z/, rule, capture: :all_but_first) + + [a, b, c, d] = Enum.map(ranges, &String.to_integer/1) + {name, {a..b, c..d}} + end + + def valid?(ticket, rules) do + Enum.all?(ticket, fn field -> + Enum.any?(rules, fn {_name, {range1, range2}} -> field in range1 || field in range2 end) + end) + end + + def transpose_tickets(tickets), do: transpose_tickets(tickets, [], 0, length(hd(tickets))) + def transpose_tickets(_tickets, columns, stop, stop), do: columns + + def transpose_tickets(tickets, columns, field_index, stop) do + {remaining_columns, column} = next_column(tickets) + + transpose_tickets(remaining_columns, [{field_index, column} | columns], field_index + 1, stop) + end + + def next_column(tickets) do + Enum.map_reduce(tickets, [], fn [field | rest], column -> {rest, [field | column]} end) + end + + def identify_column(column, rules) do + Enum.filter(rules, fn {_field, {range1, range2}} -> + Enum.all?(column, fn val -> val in range1 || val in range2 end) + end) + |> Enum.map(&elem(&1, 0)) + end + + # Probably overcomplicated this. + # First find which columns satisfy which rules. + # The number of valid fields for each column is unique, which doesn't seem like a coincidence. + # Then allocate the columns to fields starting from the column with the smallest number + # of valid columns - need to filter out the known values for the rest of the columns. + # It's the final filtering part that makes me think I'm missing a trick. + def identify_columns(transposed_tickets, rules) do + {field_map, by_valid_count} = + Enum.reduce(transposed_tickets, {%{}, %{}}, fn {id, column}, {field_map, by_valid_count} -> + names = identify_column(column, rules) + valid_count = length(names) + + {Map.put(field_map, id, names), Map.put(by_valid_count, valid_count, id)} + end) + + {identified, _seen} = + by_valid_count + |> Enum.sort(fn {k1, _}, {k2, _} -> k1 <= k2 end) + |> Enum.reduce({%{}, MapSet.new()}, fn {_, col}, {identified, seen} -> + field = field_map[col] |> MapSet.new() |> MapSet.difference(seen) |> Enum.at(0) + {Map.put(identified, field, col), MapSet.put(seen, field)} + end) + + identified + end +end + +Day16Part2.run() diff --git a/day16/input b/day16/input new file mode 100644 index 0000000..c6c4382 --- /dev/null +++ b/day16/input @@ -0,0 +1,266 @@ +departure location: 49-258 or 268-960 +departure station: 37-117 or 128-968 +departure platform: 31-70 or 78-974 +departure track: 26-234 or 247-952 +departure date: 49-625 or 635-969 +departure time: 26-777 or 799-974 +arrival location: 49-735 or 757-971 +arrival station: 28-381 or 399-970 +arrival platform: 49-77 or 95-957 +arrival track: 29-467 or 477-950 +class: 40-218 or 234-967 +duration: 45-900 or 911-970 +price: 42-442 or 452-966 +route: 45-104 or 112-953 +row: 49-877 or 884-957 +seat: 40-168 or 184-953 +train: 43-913 or 920-949 +type: 43-292 or 315-955 +wagon: 48-547 or 558-954 +zone: 40-929 or 935-954 + +your ticket: +59,101,191,149,167,197,199,137,163,131,113,67,103,97,61,139,157,151,193,53 + +nearby tickets: +765,721,63,432,949,277,838,143,894,681,976,948,949,605,810,368,595,729,593,373 +205,877,327,644,328,652,102,892,156,525,884,355,195,187,106,886,405,608,163,286 +602,284,250,271,156,561,113,376,892,554,800,328,924,526,321,434,368,837,59,491 +923,604,129,647,801,838,620,152,50,673,804,54,371,354,687,877,983,334,723,566 +569,870,114,688,613,521,368,501,857,480,406,927,402,125,429,357,217,651,463,821 +513,147,329,113,856,734,867,495,381,728,400,661,843,583,857,820,925,323,532,931 +70,274,713,453,195,776,379,337,221,899,139,286,866,139,888,562,776,777,651,460 +857,861,499,561,335,690,333,890,935,807,333,64,843,531,405,424,945,668,445,279 +758,590,983,582,770,543,250,601,766,151,55,420,651,498,327,861,857,319,530,372 +872,286,949,708,466,279,613,719,485,404,590,273,283,842,644,599,340,873,203,266 +773,152,616,449,415,414,875,617,114,281,66,644,602,639,694,671,203,638,97,840 +945,731,834,455,304,199,808,524,829,421,437,648,339,408,65,341,258,836,714,285 +65,94,429,586,835,408,565,186,682,674,947,329,332,365,279,573,695,198,458,887 +812,525,554,765,807,642,574,661,842,713,559,100,329,715,640,198,766,801,681,820 +164,358,106,428,286,518,334,440,845,139,134,402,289,570,813,234,341,114,945,189 +135,332,99,857,814,280,216,114,414,441,501,137,66,677,172,833,402,254,617,52 +569,836,312,136,185,809,54,206,493,724,426,509,257,257,493,358,426,406,688,701 +188,715,655,892,603,478,253,526,423,904,315,166,279,894,249,853,327,351,533,442 +438,912,675,840,462,816,595,399,761,653,825,820,858,769,426,146,671,150,124,435 +944,559,642,233,652,429,819,492,196,361,292,252,372,114,134,935,771,674,623,871 +150,699,279,604,665,866,698,424,535,827,401,111,767,207,923,414,581,568,201,868 +462,67,479,164,763,690,759,491,638,620,605,687,201,537,80,913,833,559,209,509 +188,326,700,150,648,845,435,103,714,510,733,595,635,768,304,843,104,710,486,101 +760,578,172,465,453,726,622,724,536,852,616,828,723,493,139,128,193,940,929,523 +156,251,280,661,851,526,596,621,731,980,868,575,774,699,913,516,362,492,216,773 +844,638,563,605,130,320,360,322,359,648,599,890,497,0,274,497,719,563,462,949 +564,619,482,684,485,848,347,62,562,695,898,486,436,402,610,279,849,278,928,235 +70,495,404,863,161,541,988,573,940,434,358,862,673,698,255,284,652,465,483,55 +893,160,425,13,948,210,604,656,138,584,865,695,61,147,352,771,652,770,704,133 +189,278,635,864,559,140,849,578,514,234,718,117,601,53,835,485,828,496,55,557 +658,147,128,143,864,666,682,167,675,827,153,272,288,621,443,704,890,766,332,53 +416,164,370,825,845,976,697,693,921,801,920,693,767,876,488,527,614,439,114,893 +467,944,689,572,153,592,943,520,385,693,456,542,559,890,615,373,712,334,361,723 +862,325,622,215,639,95,59,194,128,605,328,453,876,271,324,572,602,652,598,225 +615,491,867,818,670,894,830,642,461,802,639,621,117,455,998,348,402,325,587,418 +357,463,582,669,203,528,819,234,528,606,289,138,210,815,480,674,601,279,266,536 +353,896,515,477,658,418,482,287,202,757,442,222,924,669,537,593,55,155,523,625 +134,201,689,502,424,499,97,58,525,513,65,202,211,648,832,987,695,571,944,659 +185,651,380,686,626,612,635,512,461,143,437,343,897,370,70,686,850,814,503,766 +456,615,589,491,592,669,578,484,827,402,539,158,275,281,775,404,227,357,667,714 +816,522,729,608,160,137,625,857,748,65,113,199,211,857,607,836,569,892,204,564 +515,126,804,159,573,810,814,496,599,611,361,134,584,535,337,893,945,479,62,719 +645,509,576,461,517,430,611,542,692,339,666,729,351,677,368,835,299,500,406,597 +576,241,112,576,252,131,730,136,657,433,813,831,378,214,376,481,710,154,188,349 +585,942,712,291,563,143,877,592,925,571,68,350,110,591,269,357,870,759,441,595 +465,481,67,912,433,673,292,758,827,695,203,362,860,710,616,940,273,477,22,764 +509,270,939,711,406,461,921,409,568,824,365,167,613,408,732,841,886,19,770,658 +114,690,806,273,942,900,103,278,588,153,686,423,801,548,650,702,893,440,66,731 +142,671,458,871,925,945,594,377,193,361,139,497,160,865,163,688,96,723,945,996 +327,655,833,623,374,829,509,157,732,535,887,644,258,271,873,112,141,428,780,558 +765,466,52,204,174,667,803,826,712,672,759,816,943,142,717,168,927,353,505,409 +340,626,895,248,685,288,137,837,335,204,889,714,407,330,143,151,51,861,854,112 +771,891,403,537,571,193,863,624,73,811,272,515,660,432,510,570,617,606,456,663 +489,102,195,709,205,431,821,586,98,569,349,431,504,807,51,255,543,676,506,73 +762,939,856,734,352,524,855,413,725,400,573,704,759,832,666,187,502,594,632,703 +836,611,137,674,777,283,506,100,289,255,191,822,364,273,625,902,218,216,500,189 +884,354,440,584,681,638,570,211,846,285,776,248,488,994,318,810,421,685,523,504 +942,897,617,157,808,857,929,584,869,143,493,501,433,816,467,167,318,420,418,447 +665,928,366,707,369,272,692,876,661,58,504,647,643,638,563,457,849,450,566,726 +523,164,570,516,854,68,400,234,929,848,705,871,854,184,949,4,505,860,660,524 +288,855,636,814,616,132,206,662,734,425,149,540,807,336,671,980,640,58,702,759 +900,770,567,250,779,187,644,835,370,863,871,256,761,494,133,714,205,578,516,942 +271,899,374,845,125,440,216,716,132,612,643,608,414,730,323,820,329,851,348,254 +900,621,332,651,713,320,375,284,489,924,341,812,570,560,393,519,820,372,503,113 +519,622,875,402,662,158,846,128,347,669,50,78,491,766,876,615,56,253,490,483 +344,415,487,216,244,430,478,761,841,374,500,851,332,769,287,137,54,52,701,199 +337,859,147,190,876,609,315,706,729,583,12,625,356,566,723,142,196,148,200,187 +662,831,599,379,617,912,322,410,437,67,859,152,564,85,332,271,153,572,714,709 +380,73,563,541,269,677,487,69,132,598,758,692,526,510,808,806,423,723,410,535 +218,206,377,622,209,515,595,130,546,981,680,142,189,168,943,52,896,848,706,205 +143,653,861,384,497,277,522,345,568,247,911,426,427,592,61,490,456,571,53,286 +489,576,925,414,912,607,691,769,57,801,480,139,636,380,145,270,362,133,109,642 +614,513,155,200,437,400,353,700,57,825,697,929,671,895,455,585,901,805,52,851 +656,619,396,759,842,454,60,569,536,593,806,810,621,579,606,218,351,613,815,163 +58,407,726,354,683,273,318,167,291,285,524,550,807,759,651,434,144,361,405,349 +839,494,767,615,579,845,460,129,282,920,690,490,671,452,581,514,726,11,186,648 +58,505,612,340,591,692,457,268,536,528,676,664,2,405,152,477,614,465,729,896 +184,321,841,10,871,854,317,894,804,356,288,64,102,831,616,191,866,830,103,374 +270,944,576,872,248,868,891,319,399,159,612,887,60,228,586,835,290,258,99,717 +768,107,946,477,284,545,505,194,485,713,273,156,844,428,441,290,202,925,666,453 +447,540,377,838,190,66,151,828,589,195,531,943,317,654,817,524,248,898,536,771 +836,62,947,164,573,145,129,624,412,511,139,682,421,659,548,723,341,545,807,826 +130,483,144,653,659,568,766,288,200,441,681,502,829,104,628,702,667,594,537,816 +164,378,867,888,193,535,475,374,680,886,531,653,813,348,355,519,281,317,598,858 +870,545,920,255,146,735,912,324,92,187,814,807,562,316,362,255,920,442,694,895 +336,134,333,946,666,823,401,481,51,867,578,499,135,378,863,112,771,189,358,83 +833,319,649,440,503,403,184,453,638,695,368,337,482,893,810,112,433,52,555,579 +167,687,362,982,526,698,364,350,359,565,103,420,399,503,656,327,502,711,479,672 +509,764,893,596,152,217,270,347,380,729,821,612,583,277,209,56,675,683,380,314 +733,153,491,585,871,458,674,66,714,849,157,97,407,473,425,720,937,421,771,616 +517,234,151,283,840,851,546,571,480,521,353,417,14,815,925,418,104,463,275,682 +812,802,560,186,638,891,825,196,454,505,935,496,354,724,730,217,983,369,706,822 +896,185,68,130,869,428,137,135,434,222,769,720,885,60,250,826,409,868,96,402 +101,774,361,458,209,832,560,215,590,871,376,761,607,461,856,435,667,760,88,184 +50,168,358,669,132,369,525,571,589,568,651,63,661,664,130,814,913,333,169,700 +924,444,570,399,859,601,509,684,900,920,871,810,637,731,335,532,709,526,486,428 +353,857,409,719,407,187,190,542,655,774,486,667,809,924,583,148,338,325,390,65 +53,135,329,334,373,404,533,704,614,512,683,117,478,168,901,205,577,612,848,357 +189,176,586,160,616,218,435,494,283,529,70,520,456,413,565,507,651,580,484,290 +6,520,776,855,587,100,531,828,804,664,898,103,610,250,336,578,335,274,948,661 +687,527,196,676,511,367,769,827,139,170,324,877,400,150,519,929,695,168,587,50 +372,614,835,11,429,728,516,375,340,134,521,351,656,581,64,373,920,618,114,645 +271,204,347,188,59,635,617,367,861,274,664,252,272,730,665,774,584,225,680,360 +67,434,99,64,319,704,758,369,536,705,141,271,95,842,722,285,317,848,999,892 +734,675,990,825,890,767,619,215,272,576,425,581,115,663,101,867,362,516,949,647 +132,927,617,518,701,509,325,718,822,713,329,332,163,278,348,532,280,616,527,468 +112,162,489,542,575,189,855,607,335,328,870,493,610,575,715,22,570,854,375,545 +641,140,370,464,354,670,718,532,175,369,132,828,851,280,399,153,436,944,651,210 +411,826,247,175,340,199,622,824,714,133,405,684,874,202,198,706,644,330,600,592 +150,673,162,812,676,412,202,829,253,696,497,901,417,356,328,700,726,328,534,560 +606,190,596,800,149,351,939,645,581,663,477,60,102,681,269,595,615,551,564,257 +926,295,481,57,602,896,895,376,717,819,502,487,564,361,432,216,252,194,585,486 +213,441,668,859,531,532,568,511,458,318,590,515,290,347,840,509,926,388,375,872 +693,269,287,204,190,104,317,63,676,711,53,767,728,245,530,500,69,138,769,316 +502,508,926,490,331,184,808,196,439,684,855,594,145,54,464,450,57,844,546,285 +664,846,286,495,260,944,586,52,465,688,353,542,355,859,568,808,924,375,286,583 +342,659,158,861,637,156,498,946,408,378,514,404,522,858,848,477,459,984,327,272 +189,625,841,821,803,615,50,717,621,651,920,873,63,147,291,707,999,587,676,921 +712,684,612,402,642,848,460,940,254,292,272,342,388,371,696,521,697,706,606,255 +247,465,400,725,900,380,509,698,278,522,445,546,403,912,836,51,938,500,410,101 +937,356,129,837,462,208,538,777,341,431,141,425,316,804,596,507,535,100,426,121 +286,813,359,935,377,816,985,370,949,257,834,151,149,561,277,60,413,455,399,835 +191,875,187,203,417,713,350,723,123,833,833,325,771,207,373,944,642,275,584,184 +56,53,514,681,226,103,757,406,287,133,897,193,805,143,349,317,143,671,359,876 +102,682,399,731,99,733,516,512,133,496,644,347,543,403,999,561,428,257,696,728 +596,62,425,374,409,608,912,766,55,589,860,374,425,531,611,389,897,347,247,856 +621,396,286,560,602,777,247,667,140,149,284,852,537,499,361,117,706,457,161,758 +465,578,167,21,318,730,641,865,828,211,800,668,186,484,440,411,332,156,523,731 +277,507,447,187,527,493,603,829,720,687,618,873,759,60,401,728,502,579,893,771 +271,556,67,761,154,719,582,612,682,196,270,650,198,512,461,513,273,759,463,558 +433,697,332,623,185,328,114,652,587,196,415,499,466,839,399,376,734,469,708,622 +495,101,526,133,291,167,576,589,649,15,574,350,415,641,380,640,697,849,270,322 +234,116,542,484,209,494,937,813,697,870,863,179,859,896,354,768,808,535,857,279 +636,148,758,686,525,888,904,424,325,437,282,613,692,723,618,682,320,535,685,417 +459,514,860,800,514,674,418,342,237,727,251,433,676,412,479,333,929,440,272,775 +667,51,576,658,590,599,510,547,848,603,408,823,138,757,185,611,855,908,667,651 +359,591,227,334,129,189,595,439,136,674,434,760,374,498,524,581,543,722,614,349 +193,339,729,799,154,697,705,137,807,446,257,477,610,152,698,162,434,701,520,268 +503,657,858,582,346,810,433,415,260,612,862,765,574,381,728,654,678,735,455,948 +102,220,871,899,365,649,822,762,331,638,682,765,324,513,438,646,824,287,334,381 +206,196,52,581,923,640,412,507,380,407,667,352,349,330,721,419,835,666,674,916 +547,143,607,344,155,279,116,350,531,899,946,363,513,760,17,371,460,466,814,327 +585,213,418,543,732,191,330,911,353,320,770,897,146,626,281,100,673,60,842,350 +719,813,328,640,522,820,431,402,671,437,999,664,352,808,570,479,358,770,497,721 +507,828,679,325,201,360,256,708,820,842,466,622,697,659,60,370,279,896,816,393 +365,651,194,479,69,360,379,623,831,816,356,713,861,581,801,897,550,561,715,545 +677,524,816,70,258,344,829,689,864,724,270,115,220,521,869,249,839,270,461,833 +160,425,399,648,735,667,322,690,886,81,102,695,274,204,662,662,482,579,456,414 +636,597,622,929,704,825,765,460,157,646,114,921,277,716,504,554,728,891,635,801 +525,521,163,691,846,531,450,842,583,371,867,157,400,770,489,843,813,199,65,800 +947,191,897,163,727,146,279,69,99,685,337,322,322,106,207,251,765,706,888,928 +949,595,278,874,502,403,670,893,56,653,995,651,851,647,521,292,700,874,363,895 +994,137,487,159,759,810,464,132,868,134,840,603,686,185,896,129,767,724,936,515 +712,420,723,655,602,99,462,651,626,884,379,777,320,645,95,411,319,61,839,876 +668,335,649,574,513,330,770,521,771,284,323,250,830,699,593,204,585,823,417,180 +280,431,191,842,614,597,569,772,643,466,329,487,865,923,665,525,571,713,638,7 +490,544,321,278,88,460,940,675,579,490,401,547,331,657,114,495,69,332,428,343 +679,949,217,354,74,104,430,428,645,54,194,323,146,666,654,563,821,651,666,493 +252,872,647,189,724,868,467,692,461,774,370,715,198,54,431,374,332,490,679,742 +285,156,358,495,201,589,56,463,894,848,104,59,829,647,273,531,194,658,75,68 +762,258,151,684,393,247,368,871,948,370,52,655,687,762,417,840,635,356,215,328 +890,615,564,768,17,258,380,255,827,597,211,757,545,358,843,546,605,729,57,421 +810,412,187,872,601,531,576,935,884,948,330,306,670,440,819,900,191,832,103,852 +813,356,522,283,495,641,345,904,255,772,292,927,327,888,928,614,506,203,577,871 +898,539,870,641,833,340,249,271,162,390,365,377,640,439,490,373,148,685,855,438 +192,214,462,665,467,53,580,67,660,536,470,346,371,764,346,359,142,499,569,586 +146,891,355,373,942,588,218,572,635,593,189,367,776,901,405,412,248,490,537,401 +705,415,927,163,455,129,144,276,213,611,620,708,475,652,208,726,766,677,428,707 +198,602,273,61,450,659,637,586,597,947,687,713,868,193,132,454,51,827,704,855 +664,875,565,539,556,134,503,646,377,480,578,274,578,162,728,320,679,526,607,713 +287,280,808,339,835,925,799,513,547,101,684,202,374,138,236,926,874,282,419,652 +855,684,911,565,160,646,920,186,659,638,841,474,804,560,520,803,482,610,866,521 +316,977,478,635,315,814,277,318,506,291,818,55,719,190,271,863,95,697,217,516 +656,365,520,678,862,671,290,871,349,620,52,648,433,181,866,636,912,688,767,269 +466,104,512,158,652,158,703,356,54,455,938,64,850,411,474,839,335,637,848,143 +763,218,577,275,212,62,591,316,687,427,588,687,400,603,864,467,593,131,399,784 +129,280,643,866,96,400,696,538,910,601,438,571,714,768,912,203,672,337,510,610 +347,636,804,420,644,947,52,829,467,296,861,911,208,547,686,839,258,810,923,164 +416,433,115,56,400,624,721,821,465,287,846,149,211,623,565,579,711,206,452,111 +670,911,676,505,680,943,251,873,192,611,115,448,419,646,353,69,604,487,276,348 +523,496,247,279,723,920,848,61,376,767,642,521,176,873,926,687,408,431,767,464 +758,471,424,731,731,338,433,845,758,253,694,836,942,835,767,440,462,817,576,676 +604,481,288,703,208,587,205,202,713,455,102,668,380,418,912,198,468,757,776,467 +623,275,510,771,438,889,66,187,768,408,727,248,683,618,512,939,175,949,944,278 +341,892,137,289,715,617,158,588,197,277,64,373,909,679,722,599,184,422,345,678 +678,579,473,576,605,593,604,459,535,599,286,497,139,613,938,939,942,925,278,560 +461,645,256,410,275,154,191,938,280,332,511,841,770,661,61,417,486,595,946,633 +211,692,363,619,495,843,833,504,133,856,495,342,701,487,417,56,400,144,909,768 +199,579,350,196,940,636,208,412,944,582,977,947,506,103,58,614,713,430,342,160 +757,211,732,332,708,248,499,682,409,499,657,243,213,523,141,193,583,673,499,892 +68,814,400,374,525,458,839,714,517,826,762,540,443,63,347,893,207,351,253,540 +726,68,133,873,282,279,209,597,455,334,288,263,351,922,709,477,136,332,270,686 +656,729,907,452,874,255,256,818,609,50,653,567,559,685,700,285,616,604,62,829 +885,899,363,887,461,155,342,547,188,826,420,716,185,514,260,188,622,667,584,874 +638,895,251,348,908,541,641,695,613,487,824,426,55,540,809,721,863,292,573,711 +479,19,863,483,689,735,343,520,478,824,291,760,675,168,529,422,491,840,101,576 +0,150,848,281,700,853,104,856,719,531,762,537,643,925,547,69,158,61,354,321 +769,193,641,812,696,721,438,200,946,770,424,526,58,319,847,376,704,537,472,838 +411,66,621,548,380,826,593,948,407,354,438,68,330,666,531,912,839,775,422,899 +66,103,842,437,316,839,665,343,693,412,249,522,596,577,592,810,257,497,102,904 +685,889,838,142,97,823,416,67,437,469,672,566,327,590,814,315,334,713,828,588 +114,407,831,923,774,545,526,378,548,805,644,432,51,408,337,813,344,546,724,208 +710,247,320,568,684,15,346,800,799,331,234,488,765,343,615,113,763,715,844,492 +481,112,98,585,590,344,63,464,785,195,100,706,151,821,381,289,670,613,215,809 +712,284,352,315,533,988,400,371,210,711,760,817,715,353,713,332,521,334,856,345 +678,885,505,682,864,636,841,378,498,895,801,887,156,424,140,361,217,867,914,937 +857,319,638,520,66,888,373,488,107,725,465,647,273,98,209,286,774,500,186,196 +885,157,192,939,477,799,889,337,937,138,904,281,518,614,148,512,250,347,115,423 +672,651,91,321,509,128,911,831,936,145,599,406,727,810,578,488,67,61,370,949 +148,138,869,184,871,277,359,142,257,478,324,139,777,713,464,420,773,7,620,528 +438,813,436,53,56,255,58,202,62,456,534,357,57,604,850,341,444,734,535,354 +727,894,608,505,694,865,373,912,772,654,206,573,301,160,187,858,442,542,584,347 +196,925,820,893,865,730,218,565,917,624,135,716,51,542,190,359,378,213,763,290 +703,655,889,730,315,66,215,449,669,773,257,831,481,846,340,808,816,438,865,502 +197,345,717,67,776,609,190,330,464,363,803,378,515,819,511,606,394,846,777,441 +840,514,613,351,367,866,831,463,299,652,808,291,876,467,814,511,590,432,204,679 +610,654,277,872,476,697,328,422,625,717,287,799,824,373,721,404,347,489,500,856 +102,320,380,948,105,345,763,615,676,576,116,567,709,649,516,527,331,96,875,419 +99,660,65,986,870,355,701,544,205,576,921,588,708,807,703,333,195,654,689,939 +432,541,597,317,937,725,415,813,356,463,608,348,767,594,766,436,155,324,301,212 +381,528,532,700,664,730,515,817,913,110,56,588,859,700,723,650,133,734,608,857 +843,192,860,726,465,734,254,821,803,697,858,649,849,762,229,733,833,874,858,657 +874,609,773,545,497,678,898,319,773,359,924,391,455,671,730,941,585,865,805,646 +669,60,525,484,621,339,942,713,444,830,454,248,772,565,891,346,693,690,377,357 +333,909,660,660,769,135,648,845,638,100,149,101,351,716,727,822,644,824,218,574 +519,168,689,210,870,640,457,412,854,697,718,69,247,585,337,335,580,353,239,926 +537,697,772,606,575,248,926,604,814,454,160,346,708,668,655,208,102,762,252,986 +286,646,166,332,539,315,319,773,808,264,926,139,60,372,697,436,858,659,857,817 +759,925,485,416,810,517,389,163,605,290,413,770,770,63,168,52,319,639,154,357 +890,701,895,902,887,591,874,603,275,400,60,216,149,833,404,693,711,496,458,50 +772,51,318,868,541,722,586,211,530,132,695,802,355,975,138,520,824,681,129,141 +403,818,944,100,891,586,546,213,402,651,621,877,130,715,460,470,402,518,197,138 +834,290,941,360,558,861,566,577,151,846,362,433,410,643,929,371,593,399,222,161 +185,496,352,148,575,870,272,872,767,158,625,421,550,408,415,715,913,943,664,623 +897,59,69,469,690,114,503,815,518,731,591,191,704,277,696,645,459,426,671,277 +373,542,816,708,601,775,728,486,189,812,478,426,154,448,624,774,362,571,99,401 +274,580,572,413,823,659,511,216,473,532,467,276,166,324,900,759,153,888,770,415 +457,267,200,206,662,351,511,517,514,217,674,734,719,693,414,357,117,718,759,339 +852,484,677,772,466,850,664,524,508,942,615,588,671,264,893,134,851,63,270,55 +583,457,623,759,889,156,610,861,663,708,824,63,436,395,503,770,117,204,97,714 +643,835,772,757,607,114,212,638,924,103,595,506,205,305,525,210,640,899,942,132