Code War 2017 - Final Round Write-ups

code-war-banner

Như vậy là vòng chung kết Code War 2017 đã chính thức khép lại sau một ngày tranh tài căng thẳng. Các đề thi Code Puzzles của vòng chung kết cũng đã được mở lại cho toàn thể mọi người cùng vào thử sức. Và như đã hứa, ban tổ chức xin được gửi đến các bạn phần write-ups cho các bài tập này, hy vọng sẽ giúp các bạn giải đáp được những vướng mắc còn đang gặp phải.

Hãy để lại những comments chia sẻ với chúng tôi suy nghĩ, cảm tưởng của các bạn về những bài thi lần này, hay chia sẻ những cách giải mà bạn cho là hay, và ưng ý hơn so với của ban tổ chức nhé 😄

Where's the secret flag ? (50 point)

C: Where's the secret flag ? S: in my "HEAD" :v code-war-head

Với gợi ý

C: Client - S:CodeWar's Server

chúng ta thử curl lên server Code War xem như thế nào:

> GET /index HTTP/1.1
> User-Agent: curl/7.38.0
> Host: codewar.framgia.vn
> Accept: */*
> 
< HTTP/1.1 200 OK
* Server nginx/1.9.15 is not blacklisted
< Server: nginx/1.9.15
< Date: Tue, 25 Apr 2017 02:30:17 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 14565
< Connection: keep-alive
< Vary: Accept-Encoding
< Secret-Flag: CodeWar{see_through_your_head}
< Set-Cookie: pr=web; Path=/
< Set-Cookie: session=eyJfaWQiOnsiIGIiOiJaVGhqWkdJeE56UTJZMlZoWXpBeE1qWTJOMkUwTjJWaE1XTTFNalk1T1RRPSJ9fQ.C-BHbQ.EormyIMxI5xKYLt6Q9YTIQA1DQk; HttpOnly; Path=/
< 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="https://www.facebook.com/2008/fbml">
  <head>

Bạn thấy bí mật ở đâu rồi chứ ?

Flag: CodeWar{see_through_your_head}

Math Puzzle (150 point)

code-war-math-puzzle

Đây là một bài toán đố tiểu học rất thông thường, mỗi chữ cái sẽ đại diện cho một chữ số, tuy nhiên nếu bạn thử với hệ thập phân thì sẽ không có lời giải nào đúng. Lời giải đúng là phép toán này được thực hiện ở hệ cơ số 7. Đáp án đúng là:

               13301                 
                6543
--------------------
               43203
              56504
            103105
           116406
--------------------
           130661043

Flag: CodeWar{cfed5e7c4c127ff25be381b9da8934e0976ac7d5}

Rowet fo Nohai I (100 pt) - Wrote fo Hoian II (150 pt) - Etrow of Noahi III (350 pt)

Đây là các bài tháp Hà Nội kinh điển, thuật toán có trên mạng rất nhiều, nên các bạn có thể tự Google.

Input của server là không đổi nên các bạn tính ra output cho từng level rồi submit mỗi level 1 lần là xong. Chúc các bạn may mắn 😄

Flag:

  • Rowet fo Nohai I CodeWar{old_school_problem_is_easy}
  • Wrote fo Hoian II CodeWar{now_come_the_harder_one}
  • Etrow of Noahi III CodeWar{yeah_i_know_you_can_break_this_eventually}

Express Yourself (200 pt)

source_code.zip nc keyplease-challenge.framgia.vn 2015

Yêu cầu của bài này là phải tìm 1 string KHÔNG match với regex được định nghĩa trong file regex.txt. Trước hết chúng ta có thể thấy regex đó match với 1 string thỏa mãn 1 trong các điều kiện sau:

  • .*[^AS49BWXCcahpnz07].*: string mà trong đó có 1 kí tự không trong chuỗi AS49BWXCcahpnz07
  • .{,195}|.{197,}: string có không quá 195 kí tự hoặc có từ 197 kí tự trở lên
  • Các điều kiện còn lại có thể viết theo 2 cách như .{142}(?=[4h7Sp90]).* hoặc .{168}[pWX90BC].* nhưng ở đây đều có chung mục đích là giới hạn những kí tự có thể xuất hiện tại 1 vị trí nào đó. Ví dụ .{142}(?=[4h7Sp90]).* cho phép kí tự thứ 143 (kí tự sau 142 kí tự đầu tiên) có thể là 1 kí tự nào đó trong chuỗi 4h7Sp90.

Lấy phủ định của các điều kiện trên thì chúng ta biết string cần tìm phải thỏa mãn tất cả các điều kiện sau:

  • Chỉ chứa các kí tự trong chuỗi AS49BWXCcahpnz07 (i)
  • Có 196 kí tự (ii)
  • Kí tự thứ 143 không có trong chuỗi 4h7Sp90 (iii)
  • Kí tự thứ 168 không có trong chuỗi pWX90BC (iv)
  • ...

Các điều kiện (iii), (iv) có thể kết hợp với (i) để tìm ra kí tự ở 1 vị trí nào đó trong string cần tìm. Sử dụng đoạn code (được viết bằng Ruby) như dưới đây:

allowed_chars = 'AS49BWXCcahpnz07'.chars
 
regex = File.read('regex.txt')
patterns = regex.split('|')[3..-1]
 
unallowed_chars = Hash.new([])
patterns.each do |pattern|
  position = pattern.match(/\{(\d*)\}/)[1].to_i # get digits inside {}
  chars = pattern.match(/\[(.*)\]/)[1].chars    # get characters inside []
  unallowed_chars[position] += chars
end
 
str = 196.times.map { |i| (allowed_chars - unallowed_chars[i])[0] }.join
puts str

chúng ta sẽ tìm được string đó là

aSCChBpXc7hW9S0zACSphXCcSppzc7W0BCXz7XC0z4CCzn7haAA94h9Ch949nc77SnnhAzhz0BzBznWXSaAp0zA9chX0apccX4A04hzpzcBcBXa0Wh9apzn70WXnX7WnpSCXAc0C4h0h0azc00hAz9BX0h0cBnpWSpS4h4zSh7hAWhA0p970nnWCaanh4p9CABB7

Connect tới server và submit string này chúng ta sẽ có được flag cho bài này. Flag: CodeWar{not_so_regular_way_2_express}

Old Riddle Upgraded ! (300 point)

We got upgraded ! There are 10 houses:

  • Each house has a different color: magenta, black, white, green, gray, yellow, blue, red, brown, pink
  • The people living in the houses all have a different nationality: Norwegian, British, Irish, Danish, German, Spanish, Swiss, Swede, Greek, Italian
  • Each person has a differnet favorite drink: water, wine, espresso, tea, coffee, lemonade, soda, milk, icetea, beer
  • Each house is home to a different pet: butterflies, turtles, cats, horses, dogs, mice, birds, tortoises, fish, snakes
  • Each person prefers a different type of tabaco product: Kools, pipe, Bluemaster, Pall Mall, Blend, Cubans, Dunhill, Prince, Marlboro, Chersterfields
  • Each person prefers a different type of food: chocolate, steaks, cookies, spaghetties, waffles, pancakes, potatoes, ice cream, cheese, eggs
  • A different type of tree grows in front of each house: redwoods, oaks, birch, willows, eucalyptus, pines, firs, palm, nut, maple
  • Each person plays a different sport: Tennis, Badminton, Lacrosse, Basketball, Soccer, Rugby, Volleyball, Ice Hockey, Baseball, Football
  • Different flowers grow in front of each house: dahlias, roses, tulips, geraniums, orchids, crocuses, lilies, daffodils, cactuses, hyacinth
  • Each person drives a different type of car: VW, Porsche, Rolls Royce, Ferrari, Mercedes, Volvo, BMW, Renault, Toyota, Ford Here are the clues:
  • The Ferrari is parked in front of house ten.
  • There is one house between the Danish and the Badminton player on the right.
  • The person drinking wine lives in the blue house.
  • The geraniums grow directly next to the hyacinth.
  • There is one house between the person smoking Dunhill and the person eating cheese on the left.
  • There are two houses between the gray and brown house on the left
  • The Baseball player lives directly next to the person drinking tea.
  • The person eating spaghetties lives in the magenta house.
  • There are two houses between the Spanish and the tulips.
  • There is one house between the house where the willows grow and the brown house on the left.
  • The mice live in house two.
  • The person in house two drinks espresso.
  • The dahlias grow directly to the right of the Renault.
  • There is one house between the birds and the person smoking Cubans.
  • There are two houses between the person smoking Dunhill and the person eating pancakes.
  • The Swiss lives directly next to the eggs eating person.
  • The BMW is parked in front of house seven.
  • There are two houses between the cactuses and the person smoking Blend on the right
  • There are two houses between the horses and the person smoking Marlboro.
  • The daffodils grow directly next to the Soccer player.
  • The birch trees grow to the right of the person eating ice cream.
  • The firs grow directly next to the Tennis player.
  • There is one house between the birds and the person eating cookies on the right
  • The geraniums grow directly to the left of the white house.
  • There are two houses between the BMW driver and the person drinking beer on the right
  • The person in house one does not smoke Marlboro.
  • The cats live in the black house.
  • There is one house between the Irish and the Chersterfields smoking person on the right.
  • There is one house between the Swede and the fish on the left.
  • There are two houses between the horses and the Lacrosse player on the left
  • There is one house between the Rugby player and the person eating potatoes.
  • The Volleyball player lives directly to the left of the person eating ice cream.
  • The Ice Hockey player lives to the left of the person drinking lemonade.
  • The nut trees grow in front of house four.
  • There is one house between the Greek and the Kools smoking person.
  • There is one house between the VW driver and the person drinking icetea on the right.
  • The person in house five does not drink lemonade.
  • The redwoods grow directly next to the lilies.
  • The third house is black.
  • There is one house between the dogs and the Volvo.
  • There is one house between the house of the person eating chocolate and the magenta house on the left.
  • The orchids grow directly next to the person drinking water.
  • The Volvo driver lives directly to the right of the person drinking soda.
  • There is one house between the yellow house and the house the Swiss lives in on the left.
  • The person eating steaks lives to the right of the green house.
  • There are two houses between the Baseball player and the person smoking Bluemaster on the left
  • The lilies grow in front of house nine.
  • The Porsche is parked in front of house nine.
  • There is one house between the Italian and the cookies eating person.
  • There is one house between the person smoking Prince and the person drinking milk on the left.
  • The roses grow directly next to the person smoking Chersterfields.
  • There are two houses between the redwoods and the birds on the left
  • The maple trees grow directly next to the Soccer player.
  • There are two houses between the Ford driver and the Mercedes driver on the right
  • The Swede has tortoises.
  • The person in house five smokes Dunhill.
  • There is one house between the house where the eucalyptus trees grow and the gray house.
  • The person smoking Pall Mall lives directly to the right of the person eating steaks.
  • The cactuses grow directly to the right of the Rolls Royce.
  • The pines grow in the same garden as the crocuses.
  • The person eating ice cream lives in the green house.
  • The person in house one drinks wine.
  • The person in house nine plays Basketball.
  • The horses live in house four.
  • There are two houses between the redwoods and the daffodils on the left
  • There is one house between the roses and the dogs on the right
  • The British lives directly to the right of the driver of the VW.
  • The tortoises live in the yellow house.
  • The person drinking soda lives in the red house.
  • There are two houses between the Ford driver and the Tennis player.
  • The person with palm trees has butterflies. Where does everybody live?. Can you solve this riddle ?
Compute flag as: CodeWar{SHA1 of  'pipe'[i0] + 'German'[i1] + 'hyacinth'[i2] + 'firs'[i3] + 'spaghetties'[i4] + 'Mercedes'[i5] + 'Irish'[i6] + 'pipe'[i7] + 'spaghetties'[i8] + 'magenta'[i9] + 'cactuses'[i10] + 'Volleyball'[i11] + 'waffles'[i12] + 'tulips'[i13] + 'cactuses'[i14] } 
i0..i21 is number of the hourse that have that object

Đây là bài tập "nâng cấp" cho bài Old Riddle ở vòng loại. Các bạn có thể vào trang Code War 2017 - Online Round Write-ups để tham khảo cách làm, để rồi tự "giải quyết" bài này nhé.

Flag: CodeWar{b2d0ee723430de097dd1de38775b3bb6a92a3e8b}

EULA (100 point)

Read it. You must agree with Code War's EULA.

EULA - thứ mà chúng ta vẫn Next, Next, Next mỗi khi cài phần mềm. Nhưng task này, bạn sẽ cần đọc kĩ nó và nhận ra những điểm bất thường. Ví dụ:

You may make Qopies of the software for archival purposes and as required for modifications

hay

Problem2 Team.

SECTION 9	WARRANTIES AND REPRESENTATIONS

Q, 2, 9 là những thứ bất thường, sai chính tả trong EULA này. Tương tự như vậy đến cuối của EULA, chúng ta sẽ ghép lại được chuỗi:

Q29kZVdhcntkYW1tX3RoYXRfaHVydF9teV9leWV9

File hightlight các vị trí sai: https://codewar.framgia.vn/static/files/correct.doc việc còn lại là decode base-64 thôi 😄

Flag: CodeWar{damm_that_hurt_my_eye}

Meaningless No Pattern Numbers ? (125 point)

10.854886268472459115.76293945312510.884556614796306115.7437133789062510.865675826639414115.7052612304687510.827910669267117115.6942749023437510.779348472547026115.69702148437510.746969318460003115.6420898437510.730778438271534115.603637695312510.701092906770022115.669555664062510.671404468527436115.702514648437510.614718497179926115.6942749023437510.568822151626943115.69702148437510.541821094659076115.7739257812510.908830155722121115.9085083007812510.930404972955545115.9469604492187510.89264801504421115.9799194335937510.83330598364249115.9744262695312510.784744659837438115.988159179687510.771254010200892116.0375976562510.755064433001635116.0815429687510.73617549474053116.021118164062510.722682672936303115.9689331054687510.657908765044615115.966186523437510.595820834654049115.9689331054687510.558022013388603115.933227539062510.566122152662007115.8865356445312510.609319284131665115.444335937510.660607953624776115.4470825195312510.722682672936303115.4415893554687510.79014075032174115.438842773437510.838701200796804115.438842773437510.784744659837438115.444335937510.83330598364249115.4745483398437510.849491343257862115.5294799804687510.809026304002867115.2548217773437510.803630552703122115.19165039062510.730778438271534115.1339721679687510.657908765044615115.1229858398437510.59852057216725115.1504516601562510.585021646686444115.1998901367187510.58772147935399115.2438354492187510.763159330300516115.263061523437510.682200600084101115.268554687510.630915564033591115.285034179687510.590421288241638115.3482055664062510.601220285877382115.3921508789062510.922314600178503114.889526367187510.836003604375167114.911499023437510.768555807732435114.922485351562510.674103537369737114.944458007812510.609319284131665114.9636840820312510.676802582247122114.9911499023437510.72807987390491115.01586914062510.671404468527436115.0625610351562510.595820834654049115.0845336914062510.701092906770022115.12573242187510.776650342613944115.1449584960937510.852188818037952115.19165039062510.933101714863893115.2328491210937510.660607953624776114.6176147460937510.649811055745865114.6560668945312510.649811055745865114.757690429687510.701092906770022114.7714233398437510.741572454818735114.713745117187510.62551663717714114.6340942382812510.563422129963454114.6450805664062510.51481766953869114.6945190429687510.51481766953869114.77416992187510.539120858618368114.801635742187510.687598521992154114.461059570312510.698394077836666114.406127929687510.636314395400305114.351196289062510.555321919523905114.3374633789062510.506716181078506114.3649291992187510.506716181078506114.439086914062510.520218543737046114.4802856445312510.487811882056695114.4912719726562510.53642059890193114.4912719726562510.585021646686444114.5022583007812510.641713131230988114.5022583007812510.687598521992154114.5022583007812510.779348472547026114.515991210937510.744270898696877114.51049804687510.827910669267117114.515991210937510.922314600178503114.515991210937510.698394077836666114.1671752929687510.682200600084101114.09301757812510.498614480162155114.1012573242187510.452700836127217114.1479492187510.471607278043903114.2358398437510.52291894538631114.2605590820312510.601220285877382114.274291992187510.660607953624776114.257812510.684899573032132114.2276000976562510.879162225881382114.032592773437510.879162225881382113.9721679687510.881859432543306113.9089965820312510.881859432543306113.845825195312510.881859432543306113.8156127929687510.83330598364249113.812866210937510.768555807732435113.81835937510.641713131230988113.801879882812510.601220285877382113.801879882812510.525619323394588113.801879882812510.468906428316442113.80737304687510.393273105939041113.812866210937510.390571576337724113.87329101562510.390571576337724113.9309692382812510.390571576337724113.99688720703125

Với gợi ý: "split it to pairs and notice similar things" chúng ta sẽ chia lại như sau:

10.854886268472459	115.762939453125
10.884556614796306	115.74371337890625
10.865675826639414	115.70526123046875
10.827910669267117	115.69427490234375
10.779348472547026	115.697021484375
10.746969318460003	115.64208984375
10.730778438271534	115.6036376953125
10.701092906770022	115.6695556640625
10.671404468527436	115.7025146484375
10.614718497179926	115.69427490234375
10.568822151626943	115.697021484375
10.541821094659076	115.77392578125
10.908830155722121	115.90850830078125
10.930404972955545	115.94696044921875
10.89264801504421	115.97991943359375
10.83330598364249	115.97442626953125
10.784744659837438	115.9881591796875
10.771254010200892	116.03759765625
10.755064433001635	116.08154296875
10.73617549474053	116.0211181640625
10.722682672936303	115.96893310546875
10.657908765044615	115.9661865234375
10.595820834654049	115.96893310546875
10.558022013388603	115.9332275390625
10.566122152662007	115.88653564453125
10.609319284131665	115.4443359375
10.660607953624776	115.44708251953125
10.722682672936303	115.44158935546875
10.79014075032174	115.4388427734375
10.838701200796804	115.4388427734375
10.784744659837438	115.4443359375
10.83330598364249	115.47454833984375
10.849491343257862	115.52947998046875
10.809026304002867	115.25482177734375
10.803630552703122	115.191650390625
10.730778438271534	115.13397216796875
10.657908765044615	115.12298583984375
10.59852057216725	115.15045166015625
10.585021646686444	115.19989013671875
10.58772147935399	115.24383544921875
10.763159330300516	115.2630615234375
10.682200600084101	115.2685546875
10.630915564033591	115.2850341796875
10.590421288241638	115.34820556640625
10.601220285877382	115.39215087890625
10.922314600178503	114.8895263671875
10.836003604375167	114.9114990234375
10.768555807732435	114.9224853515625
10.674103537369737	114.9444580078125
10.609319284131665	114.96368408203125
10.676802582247122	114.99114990234375
10.72807987390491	115.015869140625
10.671404468527436	115.06256103515625
10.595820834654049	115.08453369140625
10.701092906770022	115.125732421875
10.776650342613944	115.14495849609375
10.852188818037952	115.191650390625
10.933101714863893	115.23284912109375
10.660607953624776	114.61761474609375
10.649811055745865	114.65606689453125
10.649811055745865	114.7576904296875
10.701092906770022	114.77142333984375
10.741572454818735	114.7137451171875
10.62551663717714	114.63409423828125
10.563422129963454	114.64508056640625
10.51481766953869	114.69451904296875
10.51481766953869	114.774169921875
10.539120858618368	114.8016357421875
10.687598521992154	114.4610595703125
10.698394077836666	114.4061279296875
10.636314395400305	114.3511962890625
10.555321919523905	114.33746337890625
10.506716181078506	114.36492919921875
10.506716181078506	114.4390869140625
10.520218543737046	114.48028564453125
10.487811882056695	114.49127197265625
10.53642059890193	114.49127197265625
10.585021646686444	114.50225830078125
10.641713131230988	114.50225830078125
10.687598521992154	114.50225830078125
10.779348472547026	114.5159912109375
10.744270898696877	114.510498046875
10.827910669267117	114.5159912109375
10.922314600178503	114.5159912109375
10.698394077836666	114.16717529296875
10.682200600084101	114.093017578125
10.498614480162155	114.10125732421875
10.452700836127217	114.14794921875
10.471607278043903	114.23583984375
10.52291894538631	114.26055908203125
10.601220285877382	114.2742919921875
10.660607953624776	114.2578125
10.684899573032132	114.22760009765625
10.879162225881382	114.0325927734375
10.879162225881382	113.97216796875
10.881859432543306	113.90899658203125
10.881859432543306	113.8458251953125
10.881859432543306	113.81561279296875
10.83330598364249	113.8128662109375
10.768555807732435	113.818359375
10.641713131230988	113.8018798828125
10.601220285877382	113.8018798828125
10.525619323394588	113.8018798828125
10.468906428316442	113.807373046875
10.393273105939041	113.8128662109375
10.390571576337724	113.873291015625
10.390571576337724	113.93096923828125
10.390571576337724	113.99688720703125

Và đem lên Google Maps, plot các điểm này ra: https://www.darrinward.com/lat-long/?id=2859262 Vâng, đó chính là quần đảo Trường Sa thân yêu của chúng ta :x

Flag: CodeWar{SpratlyIslands}

Who Are They ? (300 point)

http://machine-challenge.framgia.vn/

Đây là 1 bài machine learning khá cơ bản, thuộc dạng học có giám sát (Supervised learning). Chúng ta cần phải huấn luyện 1 mô hình để phân loại dữ liệu vào 1 trong các nhóm định trước. Dữ liệu đầu vào ở đây là ảnh, nhóm là tên người có mặt trong ảnh. Trong lĩnh vực machine learning có rất nhiều các thuật toán phân loại dữ liệu như cây quyết định (Decision tree), phân loại Bayes (Naive Bayes classification), máy vectơ hỗ trợ (Support vector machine - SVM), mạng nơ-ron nhân tạo (Neural network), ... Ở đây mình sẽ áp dụng SVM để giải quyết bài này.

Mỗi ảnh có kích thước 3 x 250 x 250 (ảnh màu nên có 3 channel màu RGB) có thể xem là 1 mẫu dữ liệu với 3 x 250 x 250 = 187500 đặc tính (feature). Đây là con số quá lớn, khó mà áp dụng SVM ngay được nên trước hết cần phải giảm con số này xuống. Đầu tiên là phần xử lí ảnh:

  • Đổi ảnh màu thành ảnh đen trắng
  • Crop lấy phần trung tâm với kích thước 125 x 125 của ảnh (phần này vừa đủ để chứa mặt người trong hầu hết các bức ảnh đã cho)
  • Resize phần ảnh đã crop về kích thước nhỏ hơn, mình lựa chọn crop về 22 x 22.

Như vậy là đến đây mỗi mẫu dữ liệu chỉ còn có 484 thuộc tính. Sau đó, mình sử dụng phương pháp Phân tích thành phần chính (Principal component analysis - PCA) để tiếp tục giảm con số này xuống còn khoảng 75 (thực tế mình có thử 1 vài con số từ 50 đến 100 nhưng thấy 75 mang lại kết quả tốt nhất cho bài này). Cuối cùng là áp dụng SVM để phân loại dữ liệu sau khi đã giảm số thuộc tính. Code đầy đủ cho bài này các bạn có thể tham khảo dưới đây:

import numpy as np
import os, glob, json
from PIL import Image
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.svm import SVC
from sklearn.decomposition import PCA
from collections import OrderedDict
 
def crop_and_resize(img_path, size=(22, 22), color=False):
  # load image
  img = Image.open(img_path)
  # convert to grayscale
  if not color:
    img = img.convert('L')
  # crop 50% image
  w, h = img.size
  img = img.crop((
    w / 2 - w / 4,
    h / 2 - h / 4,
    w / 2 + w / 4,
    h / 2 + h / 4
  ))
  # resize image
  img = img.resize(size, Image.BILINEAR)
  return img
 
# Load data
print 'Loading data...'
 
train_labels = json.load(open('train/labels.json'))
 
labels = list(set(train_labels.values()))
n_labels = len(labels)
 
label_values = {}
for i in range(n_labels):
  label_values[labels[i]] = i
 
train_names = []
train_images = []
train_targets = []
for img in glob.glob('train/*.png'):
  img_name = os.path.basename(img)
  train_names.append(img_name)
  train_targets.append(label_values[train_labels[img_name]])
  train_images.append(np.array(crop_and_resize(img)))
 
test_names = []
test_images = []
for img in glob.glob('test/*.png'):
  img_name = os.path.basename(img)
  test_names.append(img_name)
  test_images.append(np.array(crop_and_resize(img)))
 
n_train = len(train_images)
n_test = len(test_images)
 
targets = np.array(train_targets)
images = np.array(train_images + test_images)
data = images.reshape(images.shape[0], -1) # convert 3D to 2D
 
# Run PCA to reduce the number of features
print 'Running PCA...'
pca = PCA(n_components=75, whiten=True, svd_solver='auto')
data = pca.fit(data).transform(data)
 
# Split data for train and test
X_train = data[0:n_train]
y_train = targets[0:n_train]
X_test = data[n_train:]
 
# Run SVM to classify images
print 'Running SVM...'
clf = SVC(C=1000.0, gamma=0.005, class_weight='balanced')
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
 
results = OrderedDict()
for i in range(n_test):
  results[test_names[i]] = labels[y_pred[i]]
 
print 'Writing results...'
with open('results.json', 'w') as f:
  json.dump(results, f)
 
print 'Done'

Ở đây mình sử dụng 1 thư viện machine learning khá nổi tiếng đó là scikit-learn được viết bằng Python. Chạy code mất khoảng 10s (phần lớn thời gian là load và xử lí dữ liệu) và mình đã đạt được độ chính xác tầm 74~75%, vừa đủ để qua bài này 😄 Trong cuộc thi CodeWar lần này Ban Tổ Chức thấy có bạn đã submit kết quả với độ chính xác lên tới 86.5%, nếu bạn đó cũng đang đọc bài viết này thì xin hãy comment cho mọi người được biết phương pháp của bạn nhé 😃

Flag: CodeWar{welcome_to_sky_net_era}

Massive Garbage (150 point)

Well, you may found something interesting inside this massive garbage.

Một file zip 55MB nhưng giải nén ra được cả 1.6 GB, chứng tỏ có rất nhiều dữ liệu bị lặp trong này. Thử đoạn đầu:

ertpeurteprrqdgfwersggfftgaaaaaasdattttttttsdaaertpeurteprrqdgfwersggfftgdsdfsdfdavcxiyasfsssssasdkafsdffgsfsdhxxxxgasd9waskkafsdffgsfsdhxxxxgasd9waskertpeurteprrqdgfwersggfftgfdgdfgsseqwrqwycasfoooas...

Ta để ý thấy có những đoạn (rác) lặp đi lặp lại, ví dụ ertpeurteprrqdgfwersggfftg hoặc aaaaaasdattttttttsdaa. Cùng với gợi ý của BTC, chúng ta xác định được 10 đoạn rác và xoá chúng đi bằng script sau:

fin = open("garbage.txt", "r")
g = [
	"aaaaaasdattttttttsdaa",
	"ewasdasdasdzxcwrqwcase"
	"wewadsaswrhsfasccccccsw",
	"casdasdafbxcxzasfqawaeasc",
	"dsdfsdfdavcxiyasfsssssasd",
	"fdgdfgsseqwrqwycasfoooasff",
	"ertpeurteprrqdgfwersggfftg",
	"zasfsvcxhsdddrwerhhhddsgsz",
	"kafsdffgsfsdhxxxxgasd9wask",
	"masdassasnafgynnnnnnnnosdm"
]
t = fin.read()
for i in g:
	t = t.replace(i, "")
print t

những gì còn lại là:

aflagisresultoftwothousandseventeenmultiwithonemillionthreehundredthirtyseventhousandthreehundredthirtyoneend

Tính toán flag và submit ghi điểm thôi 😃

Flag: CodeWar{2697396627}


Trên đây là phần write-ups cho các bài Code Puzzles của vòng chung kết Code War 2017, hãy cho chúng tôi biết suy nghĩ, cảm nhận của các bạn bằng cách để lại comment ở phía dưới nhé.😄

Xin cảm ơn các bạn đã dõi theo và cổ vũ cho Code War 2017. Hẹn gặp lại trong các bài write-ups sắp tới.