首页 > 其他分享 >Advent of Code 2015: Day 9

Advent of Code 2015: Day 9

时间:2023-02-02 14:44:50浏览次数:60  
标签:src Code ordering Dublin dst Advent routes London 2015

JP's Blog

Advent of Code: Day 9

https://blog.jverkamp.com/2015/12/09/advent-of-code-day-9/

2015-12-09

Source

Part 1: Given a list of distances between cities of the form London to Dublin = 464, calculate the shortest route that visits each city exactly once.

routes = collections.defaultdict(
  lambda : collections.defaultdict(
    lambda : float("inf")
  )
)

for line in sys.stdin:
    src, dst, dist = re.match(r'(\w+) to (\w+) = (\d+)', line).groups()
    dist = int(dist)

    routes[src][dst] = dist
    routes[dst][src] = dist

best_length, best_ordering = min(
    (sum(
      routes[src][dst]
      for src, dst in zip(ordering, ordering[1:])
    ), ordering)
    for ordering in itertools.permutations(routes.keys())
)

print(best_length)

There are a few neat tricks here that I’ve used. First routes is defined as nested defaultdict, with an eventual default value of float("inf"). This solves two problems:

  • We don’t have to explicitly check if a station exists before adding a route to it: python routes[src][dst] = dist rather than python if src in routes: routes[src][dst] = dist else: routes[src] = {dst: dist}
  • Any missing routes will have an infinite distance, which will work correctly with + and min.

We add each distance to both routes[src][dst] and routes[dst][src] so that we don’t have to worry about ordering when we calculate full routes. The other way to do this would be to sort src and dst so that src < dst is always true. I think this way is a little cleaner.

Next, we use a bunch of tools to calculate the shortest route.

First, itertools.permutations will give us every possible ordering:

>>> pprint.pprint(list(itertools.permutations(routes.keys())))
[('London', 'Belfast', 'Dublin'),
 ('London', 'Dublin', 'Belfast'),
 ('Belfast', 'London', 'Dublin'),
 ('Belfast', 'Dublin', 'London'),
 ('Dublin', 'London', 'Belfast'),
 ('Dublin', 'Belfast', 'London')]

Next, zip over ordering and ordering[1:] will give us the pairs of stations (since zip after exhausting its shortest argument):

>>> ordering = ('Dublin', 'Belfast', 'London')
>>> pprint.pprint(list(zip(ordering, ordering[1:])))
[('Dublin', 'Belfast'), ('Belfast', 'London')]

Next, we can get the distance for each pairing and sum them all up. This is where float("inf") really comes in handy (although in this smaller example, we don’t need it):

>>> orderings = (routes[src][dst] for src, dst in zip(ordering, ordering[1:]))
>>> pprint.pprint(list(orderings))
[141, 518]
>>> pprint.pprint(sum(orderings))
659

That, we wrap up in a tuple of (distance, ordering) so that they are sortable. Then, apply min to that to find the route with the minimum distance and unpack the tuple again.

And that’s it. Minimum distance.

It’s certainly a brute force solution in that it will try every possible route to find the shortest one. There are probably a few dynamic programming tricks that could cut that down a bit. On the other hand, the input is relatively short (28 connections between 8 stations for a total of 40320 orderings), so just do them all.

Part 2: Find the longest route.

Just change min to max.

This wouldn’t work if there wasn’t a connection listed between every possible station (there is in my given input, since 8 stations will have 8*7/2 = 28 connections). That’s solveable though. Just use float("-inf") for the default distance, so that any routes with invalid stations will have an infinitely small distance.

This was a pretty cool problem again!

All posts unless otherwise mentioned are licensed under Creative Commons License

Any source code unless otherwise mentioned is licensed under the 3 clause BSD license

 

------------------------------------------------------------------------------------------
如果你觉得文章有用,欢迎打赏

 

 

标签:src,Code,ordering,Dublin,dst,Advent,routes,London,2015
From: https://www.cnblogs.com/z-cm/p/17085949.html

相关文章

  • LeetCode 1143_ 最长公共子序列
    LeetCode1143:最长公共子序列题目给定两个字符串text1和text2,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列,返回0。一个字符串的子序列......
  • 图解华为云代码检查服务CodeArts Check
    华为云代码检查服务CodeArtsCheck为用户提供代码风格、通用质量与代码安全风险等检查能力,并提供问题闭环处理、检查报告等功能,可一站式完成代码检查作业。六大特性守护软件......
  • iTOP3568开发板如何Visual Studio Code插件安装
    我们在此以ubuntu环境为例,讲解VisualStudioCode插件安装。VSCode支持多种语言,比如C/C++、Python、C#等等,对于​​嵌入式​​开发的我们主要用来编写C/C++程序的,所......
  • Codeforces Round #848 (Div. 2) A~C
    A.给出一个-1,1序列,操作是交换相邻位置的符号,一定要操作一次,求最大sum。只有4种情况,扫一遍判断是否出现即可。B题面写得真清楚啊:)#include<bits/stdc++.h>usingnam......
  • hdu-4883- (Best Coder) TIANKENG’s restaurant
    TIANKENG’srestaurantTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:131072/65536K(Java/Others)TotalSubmission(s):1622    AcceptedSubmi......
  • 图解华为云代码检查服务CodeArts Check
    华为云代码检查服务CodeArtsCheck为用户提供代码风格、通用质量与代码安全风险等检查能力,并提供问题闭环处理、检查报告等功能,可一站式完成代码检查作业。六大特性守护软......
  • C#移除字符串中的不可见Unicode字符
    背景最近发现某个数据采集的系统拿下来的数据,有些字段的JSON被莫名截断了,导致后续数据分析的时候解析JSON失败。类似这样{"title":"你好或者这样,多了个双引号啥的{"......
  • Codeforces Round #848 (Div. 2) A~F 题解
    A.FlipFlopSum能换\(-1,-1\)就换,不能能换\(1,-1\)或\(-1,1\)也可以,否则只能换\(1,1\)。B.TheForbiddenPermutation如果原序列一开始就是好的那就结束,否则......
  • 【DFS】LeetCode 124. 二叉树中的最大路径和
    题目链接124.二叉树中的最大路径和思路一个子树内部的最大路径和=左子树提供的最大路径和+根节点值+右子树提供的最大路径和。即dfs(root.left)+root.val+dfs(r......
  • Vscode配置python环境
    添加拓展在设置查找Tconda,输入虚拟环境的名称执行RunAnaconda......