- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我试图找到答案“假设L是导线的长度,对于多少L≤1500000的值,可以形成一个整数边直角三角形?”,Project Euler #75。
我不是在要求正确的答案,也不是要找到它的密码我将解释我是如何试图解决这个问题的,请你指出我错在哪里。我试图用java和common lisp解决这个问题,但总是得到相同的错误答案。因此,我很确定我的算法或基本假设中有错误,但我找不到它。我对潜在错误点的猜测是:1)设置差异时出错;2)设置参数限制时出错。
下面是我遵循的算法:
生成所有毕达哥拉斯三倍周长,并将它们集合在一起
“A”(通用Lisp的列表,因此是时差)。这一套会
生成每一个周长,是否只有一个三角形
解决方案或多个。因为这是一套每一个周边都会
只代表一次。
在附加的集合中收集重复的周长
“B”这一套只包括周长超过
一个三角形解。
A-B应该给我一张有单个三角形的周长表
解决方案这可能是我错的地方。
我用我找到的公式生成了三重态,即周长。我更喜欢用附加系数“k”的公式,因为文章说,
尽管产生了所有的原始三元组,欧几里德公式并没有
生成所有三元组例如(9、12、15)不能使用
整数m和n。可以通过插入一个
公式的参数k。
为了在合理的时间内解决这个问题,我需要对嵌套循环中的参数进行合理的限制。我为“k”和“m”设置了限制,您将在后面的完整代码中看到,借助这两个小函数:
(defun m-limit (m)
(if (> (make-peri m 1 1) 1500000)
m
(m-limit (1+ m))))
(defun k-limit (k)
(if (> (make-peri 2 1 k) 1500000)
k
(k-limit (1+ k))))
nLimit = 1500000 / (2 * k * m) - m;
package euler75v6;
import java.util.HashSet;
/**
*
* @author hoyortsetseg
*/
public class Euler75v6 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
HashSet<Long> peris = new HashSet<>();
HashSet<Long> duplicatePeris = new HashSet<>();
peris = periList(865,125000, duplicatePeris);
System.out.println("Number of all perimeters: " + peris.size());
System.out.println("Number of duplicate perimeters: " + duplicatePeris.size());
System.out.println("Number of all perimeters minus number "
+ "of duplicate perimeters: " + (peris.size() - duplicatePeris.size()));
peris.removeAll(duplicatePeris);
System.out.println("Same difference, just to confirm. After 'removeAll': " + peris.size());
}
private static Long makePeri (long m, long n, long k){
//Long a, b, c, res;
//a = k * (m * m - n * n);
//b = 2 * k * m * n;
//c = k * (m * m + n * n);
return 2 * k * (m * m + m * n);
}
private static HashSet<Long> periList (long x, long z, HashSet<Long> dupList){
HashSet<Long> res = new HashSet<>();
Long temp, nLimit;
Long limit = Long.valueOf("1500000");
for (long k = 1; k <= z; k++){
for (long m = 2; m <= x; m++){
nLimit = 1500000 / (2 * k * m) - m;
for (long n = 1; ((n <= nLimit) && (n < m)); n++){
temp = makePeri(m,n,k);
if (Long.compare(temp, limit) <= 0){ // Should be redundant but just in case.
if (res.contains(temp)){
dupList.add(temp);
}
else {
res.add(temp);
}
}
}
}
}
return res;
}
}
(defun make-peri (m n k)
(* 2 k (+ (* m m) (* m n))))
(defun peri-list (m n k all-peris dupl-peris)
(let ((n-limit (- (/ 1500000 (* 2 k m)) m)))
(cond ((> k 125000) (- (length all-peris)
(length (remove-duplicates dupl-peris))))
((> m 865) (peri-list 2 1 (1+ k) all-peris dupl-peris))
((or (>= n m) (> n n-limit))
(peri-list (1+ m) 1 k all-peris dupl-peris))
(t (let ((peri (make-peri m n k)))
(if (> peri 1500000) ;; Redundant with m n k limits but still.
(peri-list (1+ m) 1 k all-peris dupl-peris)
(if (member peri all-peris)
(peri-list m (1+ n) k all-peris (cons peri dupl-peris))
(peri-list m (1+ n) k (cons peri all-peris)
dupl-peris))))))))
(defun result () (peri-list 2 1 1 nil nil))
(defun make-peri (m n k)
(* 2 k (+ (* m m) (* m n))))
(defun peri-list* (m n k limit all-peris dupl-peris)
(let* ((n-limit (- (/ limit (* 2 k m)) m))
(k-upper-limit (1- (k-limit 1 limit)))
(m-upper-limit (1- (m-limit 2 limit)))
(dupl-peris* (remove-duplicates dupl-peris))
(difference* (set-difference all-peris dupl-peris*)))
(cond ((> k k-upper-limit) (list (sort all-peris #'<)
(sort dupl-peris* #'<)
(sort difference* #'<)))
;; (length all-peris)
;; (length dupl-peris*)
;; (length difference*)))
((> m m-upper-limit) (peri-list* 2 1 (1+ k) limit all-peris dupl-peris))
((or (>= n m) (> n n-limit))
(peri-list* (1+ m) 1 k limit all-peris dupl-peris))
(t (let ((peri (make-peri m n k)))
(if (member peri all-peris)
(peri-list* m (1+ n) k limit all-peris (cons peri dupl-peris))
(peri-list* m (1+ n) k limit (cons peri all-peris) dupl-peris))))))))
(defun m-limit (m limit)
(if (> (make-peri m 1 1) limit)
m
(m-limit (1+ m) limit)))
(defun k-limit (k limit)
(if (> (make-peri 2 1 k) limit)
k
(k-limit (1+ k) limit)))
(length...)
部分注释掉。我看到一些我不明白的行为:
CL-USER> (peri-list* 2 1 1 150 nil nil)
((12 24 30 36 40 48 56 60 70 72 80 84 90 96 108 112 120 126 132 140 144 150)
(24 48 60 72 80 84 90 96 108 112 120 132 140 144) (12 30 36 40 56 70 126 150)
13 9 8)
CL-USER> (- 22 14)
8
CL-USER> (peri-list* 2 1 1 100 nil nil)
((12 24 30 36 40 48 56 60 70 72 80 84 90 96) (24 48 60 72 80 84 90 96)
(12 30 36 40 56 70) 11 5 6)
CL-USER> (- 14 8)
6
all-peris*
和
dupl-peris*
的长度与我计算的不匹配。然而,他们的差异确实与计数相符。
(length...)
部分,让程序只列出列表并
mapcar
ed
#'length
结果:
CL-USER> (mapcar #'length (peri-list* 2 1 1 100 nil nil))
(14 8 6)
CL-USER> (mapcar #'length (peri-list 2 1 1 nil nil))
(355571 247853)
CL-USER> (- 355571 247853)
107718
all-peris
和
dupl-peris
之间的差异
(remove-duplicates...)
)给我正确的答案?
all-peris
和具有多个三角形的周长
dupl-peris
?
(let ((peri (make-peri m n k)))
(if (member peri all-peris)
(peri-list* m (1+ n) k limit all-peris (cons peri dupl-peris))
(peri-list* m (1+ n) k limit (cons peri all-peris) dupl-peris)))
length
编写我的解决方案的java版本,其中perimeters作为键,perimeters的频率作为值。这里是:
public static void main(String[] args) {
HashMap<Long, Long> perisMap = new HashMap<>();
periMap(865, 125000, perisMap);
System.out.println("Number of all perimeters (1 triangle, many triangles): " + perisMap.size());
Long uniqueCounter = Long.valueOf("0");
for (Map.Entry<Long, Long> entry : perisMap.entrySet()){
Long freq = entry.getValue();
if (freq == 1){
uniqueCounter++;
}
}
System.out.println("Number of all perimeters in the map which appear only once: " + uniqueCounter);
}
private static Long makePeri (long m, long n, long k){
//Long a, b, c, res;
//a = k * (m * m - n * n);
//b = 2 * k * m * n;
//c = k * (m * m + n * n);
return 2 * k * (m * m + m * n);
}
private static void periMap (long x, long z, HashMap<Long, Long> myMap){
Long nLimit;
Long limit = Long.valueOf("1500000");
for (long k = 1; k <= z; k++){
for (long m = 2; m <= x; m++){
nLimit = limit / (2 * k * m) - m;
for (long n = 1; ((n <= nLimit) && (n < m)); n++){
Long tempKey = makePeri(m,n,k);
Long tempVal = myMap.get(tempKey);
if (Long.compare(tempKey, limit) <= 0){
if (myMap.containsKey(tempKey)){
myMap.put(tempKey, tempVal + 1);
}
else {
myMap.put(tempKey, Long.valueOf("1"));
}
}
}
}
}
}
Number of all perimeters (1 triangle, many triangles): 355571
Number of all perimeters in the map which appear only once: 107718
最佳答案
要使用Euler公式来解决这个问题,必须遵循所有的规则,这些规则保证每个三元组只生成一次否则,将多次生成相同的三元组,并跳过有效长度,因为它们的计数过高。
规则包括只使用同素的(m,n)
对,并且m
和n
不是同时奇数的。
我认为如果你根据这些规则添加检查以避免无效对,你的算法将是正确的至少会更近一些。
关于Java代码的另一个注释:声明Long
变量很少有用。声明long
,让自动装箱在需要时进行转换。一般来说,使用Long
类型是很奇怪的。例如,Long.valueOf("1")
可以替换为1
或1L
同样地,Long.compare(tempKey, limit) <= 0
应该是tempKey <= limit
。
事实上,对于这个问题,long
是不必要的。这完全可以用int
来完成。
口齿不清
跟踪生成的每个长度的最简单方法是使用一个小整数数组以下是常见的口齿不清的想法:
(defun count-triangles (limit)
(let ((counts (make-array (1+ limit)
:element-type 'unsigned-byte
:initial-element 0))
(result 0))
(loop for m from 2 to (ceiling (sqrt limit)) do
(loop for n from 1 to (1- m)
for k1-len = (* 2 m (+ m n)) then (+ k1-len (* 2 m))
while (<= k1-len limit)
when (and (oddp (+ m n)) (= (gcd m n) 1))
do (loop for len = k1-len then (+ len k1-len)
while (<= len limit)
do (case (aref counts len)
(0 (incf result)
(incf (aref counts len)))
(1 (decf result)
(incf (aref counts len)))))))
result))
static int count() {
byte [] count = new byte[MAX + 1];
int result = 0;
for (int m = 2; m < SQRT_MAX; ++m) {
for (int n = 1; n < m; ++n) {
if (((m ^ n) & 1) == 0 || gcd(m, n) > 1) continue;
int base_len = 2 * m * (n + m);
if (base_len > MAX) break;
for (int len = base_len ; len <= MAX; len += base_len) {
switch (count[len]) {
case 0:
++result;
count[len] = 1;
break;
case 1:
--result;
count[len] = 2;
break;
default:
break;
}
}
}
}
return result;
}
关于java - 在涉及毕达哥拉斯三元组和集合的算法中找不到我的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42857877/
编辑:我似乎问错了这个问题。 我正在尝试寻找一种方法来查询一个集合是否在另一个集合中可用。例如: SELECT * FROM something WHERE (1, 3) IN (1, 2, 3, 4
这两种方法似乎 produce the same results ,但我一直很难真正说服人们第二种方法有效,因为它显然并不为人所知。 // Create some data var foo = { '
我一直在学习Kotlin,并且遇到过Collections API。在Kotlin之前,我一直在学习Java,并且我知道Java中有很多不同类型的Collections API。例如,我们使用List
为什么我会得到不同的行为: Collection col2 = new ArrayList(col); 集合 col2 = new ArrayList(); col2.addAll(col) 我正在与
所以我有一个代表专辑信息的 JSON 对象。给定“function updateRecords(id, prop, value)”我希望能够更新每个条目。正确的完成代码如下。 我得到了指示,粗体部分,
我想存储一个对象集合,这些对象根据它们所代表的值进行键控。这些键可以重复。例如: [4] => Bob [5] => Mary [5] => Sue [9] => Steve [10] =>
在检查 ArrayList API 时,我注意到一些看起来很奇怪的东西。 确实,这里是 ArrayList 构造函数实现,其中 Collection 作为参数传递: public ArrayList(
我正在为 API 编写一个 swagger 定义文件。 API 是用于 GET 请求的 /path/to/my/api: get: summary: My Custom API d
我知道scala.collection包中有两个非常有用的对象,可以帮助我们实现这个目标: JavaConverters(如果我想明确说明并准确说明我要转换的内容) JavaConversions(如
我已经阅读了无数其他帖子,但似乎无法弄清楚发生了什么,所以是时候寻求帮助了。 我正在尝试将包含集合的域实体映射到也包含集合的 dtos。 这是一个原始示例; (我提前为代码墙道歉,我尽量保持简短):
我正在创建一个具有 ArrayList 的类,因此当我调用构造函数时,它会初始化该数组: public class ElementsList { private ArrayList list;
我正在阅读事件指南和指南的开头,它说: You can also add an event listener to any element in the this.$ collection using
我是 Python 新手,想知道如何使用键在字典中存储不同数据类型的列表 例如 - {[Key1,int1,int1,String1] , [Key2,int2,int2,String2], [Key
int[] mylist = { 2, 4, 5 }; IEnumerable list1 = mylist; list1.ToList().Add(1); // why 1 does not get
我在 UI 表单中的每一行之后将以下内容添加到 HashMap 集合中 声明 Map> map = new HashMap>(); List valSetOne = new ArrayList();
我正在开发我的第一个 Java 项目,我有一个问题。问题应该很简单(虽然代码不是那么短,但没有理由被吓倒:))。我创建了一个基本的角色扮演游戏,并且有一个定义每个角色的抽象类“Character”。在
我正在开发一款应用程序,可以为用户收集推文、Facebook 状态和 Facebook 照片。目前,用户确切地设定了他们希望这种收获发生的时间和时间,并且蜘蛛会在此期间拉取数据。 when 和 to
有谁知道在 C# 中是否有与 Java 的 Set 集合等效的好方法?我知道您可以通过填充但忽略值来使用 Dictionary 或 HashTable 在某种程度上模仿集合,但这不是一种非常优雅的方式
EXISTS 该函数返回 集合中第一个元素的索引,如果集合为空,返回NULLNULLNULL Collecti
RDF集合是通过属性 rdf:parseType="Collection" 来描述仅包含指定成员的组 rdf:parseType="Collection" 属
我是一名优秀的程序员,十分优秀!