|
2540 | 2540 | },
|
2541 | 2541 | {
|
2542 | 2542 | "cell_type":"code",
|
2543 |
| -"execution_count":73, |
| 2543 | +"execution_count":14, |
2544 | 2544 | "metadata": {},
|
2545 | 2545 | "outputs": [],
|
2546 | 2546 | "source": [
|
|
2549 | 2549 | },
|
2550 | 2550 | {
|
2551 | 2551 | "cell_type":"code",
|
2552 |
| -"execution_count":74, |
| 2552 | +"execution_count":15, |
2553 | 2553 | "metadata": {},
|
2554 |
| -"outputs": [], |
| 2554 | +"outputs": [ |
| 2555 | + { |
| 2556 | +"name":"stdout", |
| 2557 | +"output_type":"stream", |
| 2558 | +"text": [ |
| 2559 | +"17738\n" |
| 2560 | + ] |
| 2561 | + } |
| 2562 | + ], |
2555 | 2563 | "source": [
|
2556 |
| -"## solution 1\n" |
| 2564 | +"## solution 1\n", |
| 2565 | +"with input_data as file:\n", |
| 2566 | +" inp = file.read().strip().replace(\"points with\",\"points () with\")\n", |
| 2567 | +"\n", |
| 2568 | +"types = ['slashing', 'fire', 'bludgeoning', 'radiation', 'cold']\n", |
| 2569 | +"\n", |
| 2570 | +"def parse_dmg(ss):\n", |
| 2571 | +" dtype = ss[ss.rfind(\"\")+1:]\n", |
| 2572 | +" dnum = int(ss[:ss.rfind(\"\")])\n", |
| 2573 | +" return [0 if ty != dtype else dnum for ty in types]\n", |
| 2574 | +"\n", |
| 2575 | +"def parse_res(ss):\n", |
| 2576 | +" tp = [1, 1, 1, 1, 1]\n", |
| 2577 | +" for p in ss.split(\";\"):\n", |
| 2578 | +" if len(p) == 0:\n", |
| 2579 | +" continue\n", |
| 2580 | +" mul = 1\n", |
| 2581 | +" if p[:4] ==\"weak\":\n", |
| 2582 | +" mul = 2\n", |
| 2583 | +" p = p[8:]\n", |
| 2584 | +" elif p[:6] ==\"immune\":\n", |
| 2585 | +" mul = 0\n", |
| 2586 | +" p = p[10:]\n", |
| 2587 | +" for dt in p.split(\"&\"):\n", |
| 2588 | +" tp[types.index(dt)] = mul\n", |
| 2589 | +" return tp\n", |
| 2590 | +"\n", |
| 2591 | +"vals = inp.split(\"\\n\\n\")\n", |
| 2592 | +"immune = vals[0]\n", |
| 2593 | +"infect = vals[1]\n", |
| 2594 | +"immune = [s.replace(\",\",\"&\").replace(\" units each with\",\",\").replace(\" hit points (\",\",\").replace(\") with an attack that does\",\",\").replace(\" damage at initiative\",\",\") for s in immune.split(\"\\n\")[1:]]\n", |
| 2595 | +"infect = [s.replace(\",\",\"&\").replace(\" units each with\",\",\").replace(\" hit points (\",\",\").replace(\") with an attack that does\",\",\").replace(\" damage at initiative\",\",\") for s in infect.split(\"\\n\")[1:]]\n", |
| 2596 | +"\n", |
| 2597 | +"def info(v):\n", |
| 2598 | +" v = v.split(\",\")\n", |
| 2599 | +" dmg = parse_dmg(v[3])\n", |
| 2600 | +" return [int(v[0]),int(v[1]),parse_res(v[2]),dmg,int(v[4]),0]\n", |
| 2601 | +"\n", |
| 2602 | +"immune = list(map(info, immune))\n", |
| 2603 | +"infect = list(map(info, infect))\n", |
| 2604 | +"\n", |
| 2605 | +"def calc_dmg(ak,df):\n", |
| 2606 | +" return sum(a*b for a,b in zip(ak[3],df[2]))\n", |
| 2607 | +"\n", |
| 2608 | +"def run_combat(immune,infect):\n", |
| 2609 | +" while len(immune) > 0 and len(infect) > 0:\n", |
| 2610 | +" for i in immune:\n", |
| 2611 | +" i[-1] = i[0] * max(i[3])\n", |
| 2612 | +" for i in infect:\n", |
| 2613 | +" i[-1] = i[0] * max(i[3])\n", |
| 2614 | +" immune.sort(key=lambda v : 1000*(-v[-1])-v[-2])\n", |
| 2615 | +" infect.sort(key=lambda v : 1000*(-v[-1])-v[-2])\n", |
| 2616 | +"\n", |
| 2617 | +" im_tgs = []\n", |
| 2618 | +" for ak in immune:\n", |
| 2619 | +" best_choice = (0, 100000000, 0, None)\n", |
| 2620 | +" for idx, df in enumerate(infect):\n", |
| 2621 | +" if idx in im_tgs:\n", |
| 2622 | +" continue\n", |
| 2623 | +" tc = (calc_dmg(ak, df), df[-1], df[-2], idx)\n", |
| 2624 | +" if tc > best_choice:\n", |
| 2625 | +" best_choice = tc\n", |
| 2626 | +" im_tgs.append(best_choice[3])\n", |
| 2627 | +"\n", |
| 2628 | +" if_tgs = []\n", |
| 2629 | +" for ak in infect:\n", |
| 2630 | +" best_choice = (0, 100000000, 0, None)\n", |
| 2631 | +" for idx, df in enumerate(immune):\n", |
| 2632 | +" if idx in if_tgs:\n", |
| 2633 | +" continue\n", |
| 2634 | +" tc = (calc_dmg(ak, df), df[-1], df[-2], idx)\n", |
| 2635 | +" if tc > best_choice:\n", |
| 2636 | +" best_choice = tc\n", |
| 2637 | +" if_tgs.append(best_choice[3])\n", |
| 2638 | +"\n", |
| 2639 | +" all_units = []\n", |
| 2640 | +" for i,v in enumerate(immune):\n", |
| 2641 | +" all_units.append([0, i, v])\n", |
| 2642 | +" for i,v in enumerate(infect):\n", |
| 2643 | +" all_units.append([1, i, v])\n", |
| 2644 | +"\n", |
| 2645 | +" all_units.sort(key=lambda v : -v[2][-2])\n", |
| 2646 | +"\n", |
| 2647 | +" alive_immune = immune[:]\n", |
| 2648 | +" alive_infect = infect[:]\n", |
| 2649 | +"\n", |
| 2650 | +" total_deathtoll = 0\n", |
| 2651 | +"\n", |
| 2652 | +" for unit in all_units:\n", |
| 2653 | +" if unit[0] == 0:\n", |
| 2654 | +" if unit[2] not in alive_immune:\n", |
| 2655 | +" continue\n", |
| 2656 | +" if im_tgs[unit[1]] is None:\n", |
| 2657 | +" continue\n", |
| 2658 | +" taken_damage = unit[2][0] * calc_dmg(unit[2],infect[im_tgs[unit[1]]])\n", |
| 2659 | +" death_toll = (taken_damage)//infect[im_tgs[unit[1]]][1]\n", |
| 2660 | +" infect[im_tgs[unit[1]]][0] -= death_toll\n", |
| 2661 | +" total_deathtoll += death_toll\n", |
| 2662 | +" if infect[im_tgs[unit[1]]][0] <= 0:\n", |
| 2663 | +" alive_infect.remove(infect[im_tgs[unit[1]]])\n", |
| 2664 | +" else:\n", |
| 2665 | +" if unit[2] not in alive_infect:\n", |
| 2666 | +" continue\n", |
| 2667 | +" if if_tgs[unit[1]] is None:\n", |
| 2668 | +" continue\n", |
| 2669 | +" taken_damage = unit[2][0] * calc_dmg(unit[2],immune[if_tgs[unit[1]]])\n", |
| 2670 | +" death_toll = (taken_damage)//immune[if_tgs[unit[1]]][1]\n", |
| 2671 | +" immune[if_tgs[unit[1]]][0] -= death_toll\n", |
| 2672 | +" total_deathtoll += death_toll\n", |
| 2673 | +" if immune[if_tgs[unit[1]]][0] <= 0:\n", |
| 2674 | +" alive_immune.remove(immune[if_tgs[unit[1]]])\n", |
| 2675 | +"\n", |
| 2676 | +" ## Stalemate\n", |
| 2677 | +" if total_deathtoll == 0:\n", |
| 2678 | +" return False\n", |
| 2679 | +"\n", |
| 2680 | +" immune = alive_immune\n", |
| 2681 | +" infect = alive_infect\n", |
| 2682 | +"\n", |
| 2683 | +" return tuple(map(lambda w : sum(v[0] for v in w), [infect,immune]))\n", |
| 2684 | +"\n", |
| 2685 | +"def dcopy(m):\n", |
| 2686 | +" if type(m) is list:\n", |
| 2687 | +" return [dcopy(d) for d in m]\n", |
| 2688 | +" else:\n", |
| 2689 | +" return m\n", |
| 2690 | +"\n", |
| 2691 | +"def rboost(b):\n", |
| 2692 | +" im_copy = dcopy(immune)\n", |
| 2693 | +" if_copy = dcopy(infect)\n", |
| 2694 | +" for i in im_copy:\n", |
| 2695 | +" i[3][max(enumerate(i[3]),key=lambda v : v[1])[0]] += b\n", |
| 2696 | +" return run_combat(im_copy, if_copy)\n", |
| 2697 | +"\n", |
| 2698 | +"print(run_combat(dcopy(immune),dcopy(infect))[0])" |
2557 | 2699 | ]
|
2558 | 2700 | },
|
2559 | 2701 | {
|
2560 | 2702 | "cell_type":"code",
|
2561 |
| -"execution_count":75, |
| 2703 | +"execution_count":16, |
2562 | 2704 | "metadata": {},
|
2563 |
| -"outputs": [], |
| 2705 | +"outputs": [ |
| 2706 | + { |
| 2707 | +"name":"stdout", |
| 2708 | +"output_type":"stream", |
| 2709 | +"text": [ |
| 2710 | +"3057\n" |
| 2711 | + ] |
| 2712 | + } |
| 2713 | + ], |
2564 | 2714 | "source": [
|
2565 |
| -"## solution 2\n" |
| 2715 | +"## solution 2\n", |
| 2716 | +"low = 1\n", |
| 2717 | +"high = 100\n", |
| 2718 | +"while high > low:\n", |
| 2719 | +" mid = (high+low)//2\n", |
| 2720 | +" res = rboost(mid)\n", |
| 2721 | +" if res == False or res[1] == 0:\n", |
| 2722 | +" low = mid + 1\n", |
| 2723 | +" else:\n", |
| 2724 | +" high = mid\n", |
| 2725 | +"\n", |
| 2726 | +"print(rboost(high)[1])" |
2566 | 2727 | ]
|
2567 | 2728 | },
|
2568 | 2729 | {
|
|
2608 | 2769 | "name":"python",
|
2609 | 2770 | "nbconvert_exporter":"python",
|
2610 | 2771 | "pygments_lexer":"ipython3",
|
2611 |
| -"version":"3.6.7" |
| 2772 | +"version":"3.6.5" |
2612 | 2773 | }
|
2613 | 2774 | },
|
2614 | 2775 | "nbformat":4,
|
|