Snippets

cia_rana オフラインリアルタイムどう書く E08 の問題 - 白黒陣取りゲーム

Updated by cia_rana

File e08.rb Modified

  • Ignore whitespace
  • Hide word diff
   }
   
   # 共通エリアの面積を引く
-  # 共通エリアが発生しうるのは右下の頂点を共有している場合のみ
+  # 共通エリアが発生しうるのは右上または右下の頂点を共有している場合のみ
   self_area.combination(2).each{|a, b|
-    if a[2] == b[2] && a[3] == b[3]
-      area_sum -= (a[2] - [a[0], b[0]].max) * (a[3] - [a[1], b[1]].max) 
+    if a[2] == b[2]
+      if a[3] == b[3]
+        area_sum -= (a[2] - [a[0], b[0]].max) * (a[3] - [a[1], b[1]].max) 
+      elsif a[1] == b[1]
+        area_sum -= ([a[0], b[0]].max - [a[0], b[0]].min) * (a[3] - [a[1], b[1]].max)
+      end
     end
   }
   
     assert_equal solve("a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8d1d2d3d4d5d6d7d8e1e2e3e4e5e6e7e8f1f2f3f4f5f6f7f8g1g2g3g4g5g6g7g8h1h2h3h4h5h6h7h8i1i2i3i4i5i6i7i8j1j2j3j4j5j6j7j8k1k2k3k4k5k6k7k8l1l2l3l4l5l6l7l8m1m2m3m4m5m6m7m8n1n2n3n4n5n6n7n8o1o2o3o4o5o6o7o8p1p2p3p4p5p6p7p8q1q2q3q4q5q6q7q8r1r2r3r4r5r6r7r8s1s2s3s4s5s6s7s8,a12a13a14a15a16a17a18a19b12b13b14b15b16b17b18b19c12c13c14c15c16c17c18c19d12d13d14d15d16d17d18d19e12e13e14e15e16e17e18e19f12f13f14f15f16f17f18f19g12g13g14g15g16g17g18g19h12h13h14h15h16h17h18h19i12i13i14i15i16i17i18i19j12j13j14j15j16j17j18j19k12k13k14k15k16k17k18k19l12l13l14l15l16l17l18l19m12m13m14m15m16m17m18m19n12n13n14n15n16n17n18n19o12o13o14o15o16o17o18o19p12p13p14p15p16p17p18p19q12q13q14q15q16q17q18q19r12r13r14r15r16r17r18r19s12s13s14s15s16s17s18s19"), "126,126"
     assert_equal solve("a1a2a3a4a5a6a7a8a9b1b2b3b4b5b6b7b8b9c1c2c3c4c5c6c7c8c9d1d2d3d4d5d6d7d8d9e1e2e3e4e5e6e7e8e9f1f2f3f4f5f6f7f8f9g1g2g3g4g5g6g7g8g9h1h2h3h4h5h6h7h8h9i1i2i3i4i5i6i7i8i9j1j2j3j4j5j6j7j8j9k1k2k3k4k5k6k7k8k9l1l2l3l4l5l6l7l8l9m1m2m3m4m5m6m7m8m9n1n2n3n4n5n6n7n8n9o1o2o3o4o5o6o7o8o9p1p2p3p4p5p6p7p8p9q1q2q3q4q5q6q7q8q9r1r2r3r4r5r6r7r8r9s1s2s3s4s5s6s7s8s9,a11a12a13a14a15a16a17a18a19b11b12b13b14b15b16b17b18b19c11c12c13c14c15c16c17c18c19d11d12d13d14d15d16d17d18d19e11e12e13e14e15e16e17e18e19f11f12f13f14f15f16f17f18f19g11g12g13g14g15g16g17g18g19h11h12h13h14h15h16h17h18h19i11i12i13i14i15i16i17i18i19j11j12j13j14j15j16j17j18j19k11k12k13k14k15k16k17k18k19l11l12l13l14l15l16l17l18l19m11m12m13m14m15m16m17m18m19n11n12n13n14n15n16n17n18n19o11o12o13o14o15o16o17o18o19p11p12p13p14p15p16p17p18p19q11q12q13q14q15q16q17q18q19r11r12r13r14r15r16r17r18r19s11s12s13s14s15s16s17s18s19"), "144,144"
     assert_equal solve("b1d1f1h1j1l1n1p1r1a2c2e2g2i2k2m2o2q2s2b3d3f3h3j3l3n3p3r3a4c4e4g4i4k4m4o4q4s4b5d5f5h5j5l5n5p5r5a6c6e6g6i6k6m6o6q6s6b7d7f7h7j7l7n7p7r7a8c8e8g8i8k8m8o8q8s8b9d9f9h9j9l9n9p9r9a10c10e10g10i10k10m10o10q10s10b11d11f11h11j11l11n11p11r11a12c12e12g12i12k12m12o12q12s12b13d13f13h13j13l13n13p13r13a14c14e14g14i14k14m14o14q14s14b15d15f15h15j15l15n15p15r15a16c16e16g16i16k16m16o16q16s16b17d17f17h17j17l17n17p17r17a18c18e18g18i18k18m18o18q18s18b19d19f19h19j19l19n19p19r19,a1c1e1g1i1k1m1o1q1s1b2d2f2h2j2l2n2p2r2a3c3e3g3i3k3m3o3q3s3b4d4f4h4j4l4n4p4r4a5c5e5g5i5k5m5o5q5s5b6d6f6h6j6l6n6p6r6a7c7e7g7i7k7m7o7q7s7b8d8f8h8j8l8n8p8r8a9c9e9g9i9k9m9o9q9s9b10d10f10h10j10l10n10p10r10a11c11e11g11i11k11m11o11q11s11b12d12f12h12j12l12n12p12r12a13c13e13g13i13k13m13o13q13s13b14d14f14h14j14l14n14p14r14a15c15e15g15i15k15m15o15q15s15b16d16f16h16j16l16n16p16r16a17c17e17g17i17k17m17o17q17s17b18d18f18h18j18l18n18p18r18a19c19e19g19i19k19m19o19q19s19"), "0,0"
+    assert_equal solve("a1a2a3a4a5b1b2b3b4b5c1c2c4c5d1d2d3d4d5e1e2e3e4e5,l9"), "16,0"
   end
 end
Updated by cia_rana

File e08.rb Modified

  • Ignore whitespace
  • Hide word diff
 end
 
 def calc_area friends, enemies
+  # 自陣営の全ての駒の対角となりうる駒を集める
   self_area = []
   friends.each.with_index(1){|(r, c), i|
     # 自分のy座標より大きいy座標の値を持ち、かつ同じx座標を持つ自陣営の駒を集める
Updated by cia_rana

File e08.rb Modified

  • Ignore whitespace
  • Hide word diff
 require "minitest/autorun"
 
+def get_opposite_angle friends, enemies, i, y, x
+  r, c = friends[i-1]
+  friends[i..-1].each{|s, d| 
+    y.each{|t|
+      # y座標が一致しなければスキップ
+      next unless t == s
+      x.each{|e|
+        # x座標が一致しなければスキップ
+        # x, y座標が一致しても自分の駒とエリアを構成する対角の駒との間に敵の駒があってもスキップ
+        if e == d && !enemies.index{|u, f| r <= u && u <= t && c <= f && f <= e }
+          return [t, e]
+        end
+      }
+    }
+  }
+  return []
+end
+
 def calc_area friends, enemies
   self_area = []
   friends.each.with_index(1){|(r, c), i|
     next unless x = friends[i..-1].select{|s,_|s == r}.map{|_,d|d}
     
     # 自陣営の中から上で集めたx,y座標と一致する駒を抜き出す
-    flg = false
-    z = []
-    friends[i..-1].each{|s, d| 
-      y.each{|t|
-        # y座標が一致しなければスキップ
-        next unless t == s
-        x.each{|e|
-          # x座標が一致しなければスキップ
-          # x, y座標が一致しても自分の駒とエリアを構成する対角の駒との間に敵の駒があってもスキップ
-          if e == d && !enemies.index{|u, f| r <= u && u <= t && c <= f && f <= e }
-            z = [t, e]
-            flg = true
-            break
-          end
-        }
-        break if flg
-      }
-      break if flg
-    }
-    next unless flg
+    z = get_opposite_angle friends, enemies, i, y, x
+    next if z.empty?
     
     self_area << [r, c, *z]
   }
Updated by cia_rana

File e08.rb Modified

  • Ignore whitespace
  • Hide word diff
 
 def calc_area friends, enemies
   self_area = []
-  friends.each_with_index{|(r, c),i|
-    # 自分のy座標より大きいy座標の値を集めてソートする
-    next unless y = friends[i+1..-1].select{|s, d| d == c }.map{|s,_|s}.sort
-    # 自分のx座標より大きいx座標の値を集めてソートする
-    next unless x = friends[i+1..-1].select{|s, d| s == r }.map{|_,d|d}.sort
+  friends.each.with_index(1){|(r, c), i|
+    # 自分のy座標より大きいy座標の値を持ち、かつ同じx座標を持つ自陣営の駒を集める
+    next unless y = friends[i..-1].select{|_,d|d == c}.map{|s,_|s}
+    # 自分のx座標より大きいx座標の値を持ち、かつ同じy座標を持つ自陣営の駒を集める
+    next unless x = friends[i..-1].select{|s,_|s == r}.map{|_,d|d}
     
     # 自陣営の中から上で集めたx,y座標と一致する駒を抜き出す
     flg = false
     z = []
-    friends[i+1..-1].each{|s, d| 
+    friends[i..-1].each{|s, d| 
       y.each{|t|
         # y座標が一致しなければスキップ
         next unless t == s
 end
 
 def solve input
-  w, b = input.split(?,).map{|e|e.scan(/\d+/).map(&:to_i).zip(e.scan(/[a-z]/).map(&:ord)).sort_by{|r,_|r}.sort_by.with_index{|(_,c),i|[c,i]}}
-  "%s,%s" % [calc_area(w, b), calc_area(b, w)]
+  w, b = input.split(?,).map{|e|
+    e.scan(/\d+/).map(&:to_i).zip(e.scan(/[a-z]/).map(&:ord))
+    .sort_by{|r,_|r}
+    .sort_by.with_index{|(_,c),i|[c,i]}
+  }
+  [calc_area(w, b), calc_area(b, w)] * ?,
 end
 
 class TestRunner < Minitest::Test
Updated by cia_rana

File e08.rb Modified

  • Ignore whitespace
  • Hide word diff
 
 def calc_area friends, enemies
   self_area = []
-  friends.each{|r, c|
+  friends.each_with_index{|(r, c),i|
     # 自分のy座標より大きいy座標の値を集めてソートする
-    next unless y = friends.select{|s, d| r < s && d == c }.map{|s,_|s}.sort
+    next unless y = friends[i+1..-1].select{|s, d| d == c }.map{|s,_|s}.sort
     # 自分のx座標より大きいx座標の値を集めてソートする
-    next unless x = friends.select{|s, d| c < d && s == r }.map{|_,d|d}.sort
+    next unless x = friends[i+1..-1].select{|s, d| s == r }.map{|_,d|d}.sort
     
     # 自陣営の中から上で集めたx,y座標と一致する駒を抜き出す
     flg = false
     z = []
-    friends.each{|s, d| 
+    friends[i+1..-1].each{|s, d| 
       y.each{|t|
         # y座標が一致しなければスキップ
         next unless t == s
 end
 
 def solve input
-  w, b = input.split(?,).map{|e|e.scan(/\d+/).map(&:to_i).zip(e.scan(/[a-z]/).map(&:ord))}
+  w, b = input.split(?,).map{|e|e.scan(/\d+/).map(&:to_i).zip(e.scan(/[a-z]/).map(&:ord)).sort_by{|r,_|r}.sort_by.with_index{|(_,c),i|[c,i]}}
   "%s,%s" % [calc_area(w, b), calc_area(b, w)]
 end
 
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.