Jetbrains第三組謎題解答

好了,最後來介紹一下Jetbrains第三組謎題的解決辦法吧。

線索一:推特代碼

先看看這次的推特代碼,和前兩組不太一樣,這次是真的無意義隨機字符串了。不過之前一段時間我正好研究了某軟件的配置,它的配置分享方式就是用base64方式加密,這次我看到這個貌似也有點像,於是就把代碼複製到Python中試了一下,還真讓我蒙對了。

推特代碼

fun twitterCode3() {
    val sss = "SGF2ZSB5b3Ugc2VlbiB0aGUgcG9zdCBvbiBvdXIgSW5zdGFncmFtIGFjY291bnQ/"
    println(Base64.getDecoder().decode(sss).map { it.toChar() }.joinToString(separator = ""))
}

解出來的密文如下。

Have you seen the post on our Instagram account?

線索二:Instagram圖片

那我們就看看Jetbrains的Instagram有啥吧。果然還真有這麼一張圖片,圖片說明中讓我們看看另一個網頁,它是一個Kotlin小代碼。

Instagram

打開之後就是這麼一個東西,顯然,還是移位加密方式。不過如果你還記得第一個謎題最後的密文,應該就會輕鬆記得移位距離應該是3,因爲它們中都出現了井號(也就是移位以後的空格)。所以把n改成3就完事了。
解決問題

當然假如你不確定的話,也不用一個一個試,寫個Kotlin代碼,循環一遍,看看結果就明白了。循環第三遍的時候,就會顯示出正確的密文。

fun tryDecrypt() {
    val tryFunc = fun(n: Int) {
        val s =
            "Zh#kdyh#ehhq#zrunlqj#552:#rq#wkh#ylghr#iru#wkh#iluvw#hslvrgh#ri#wkh#SksVwrup#HDS1#Li#zh#jdyh#|rx#d#foxh/#lw#zrxog#eh#hdv|#dv#sl1"
        for (c in s) {
            print(c - n)
        }
        println()
    }
    (1..3).forEach { tryFunc(it) }
}

密文如下。

We have been working 22/7 on the video for the first episode of the PhpStorm EAP. If we gave you a clue, it would be easy as pi.

線索三:YouTube視頻

好吧,我雖然英語過了4級,但是對於上面簡單一句話還是沒明白到底啥意思。不過最後還是乾脆求助谷歌,谷歌倒是遠遠比我瞭解Jetbrains,第一個結果就是YouTube上PhpStorm EAP版的介紹視頻。

在視頻的3分14秒,視頻畫面發生了一點抖動,有大概一秒鐘的時間,顯示了另外一個地址。值得一提的是,這個視頻早在2月份就發佈了,也就是說Jetbrains早早的就在產品中埋下了彩蛋。
神祕地址

訪問這個地址,發現這是一個限時一分鐘的問答題。感覺有點像B站註冊會員時的答題一樣。問題的答案其實就藏在Jetbrains的20週年年度報告裏,注意以下一些重要信息即可:

  • 創始人圖片
  • Jetbrains僱員數目
  • Jetbrains主要工作國家
  • 接受額外基金支持
  • 最新推出的Jetbrains產品
  • 增長最快的國家和地區

其實就算回答錯了也沒關係,反正不限制次數,可以隨時答題,而且總共五道題,記住正確答案多試幾次也可以嘗試出來。
問答題

全部選對之後,就會顯示出最後一個提示,告訴我們謎題隱藏在某個版本的Jetbrains IDEA社區版的每日提示中,但是需要先知道版本號才能下載安裝。而構建號就藏在第二段話當中。這第二段話,我對着有道詞典查了大半天,最後扔到谷歌翻譯裏面也沒看懂到底講了啥意思。

下一個提示

但是注意到每個單詞的首字母都大寫了,於是嘗試把首字母連起來。就可以得到下面一段話。

.Net day call for speakers blog post image hides the next clue.

線索四:.NET博客

谷歌一下,就可以發現這指的是一篇Jetbrains的 .NET博客,標題是call for speakers,在博客中果然找到了一個圖片。圖片上沒有發現任何問題,所以再次查看一下網頁源代碼。

博客圖片

這下終於看到了,在圖片的alt屬性上,寫了我們要尋找的版本號是201_6303。
網頁源代碼

線索五:Jetbrains社區版每日提示

好了,現在有了版本號,返回到上面一條線索中,線索提示了我們到Confluence網站上尋找Jetbrains社區版。不過其實也不用這麼麻煩的去尋找,因爲由於Jetbrains Quest熱度的關係,這個版本號已經被頂到了熱度第一的位置。

要尋找的版本號

點進去下載安裝軟件即可,這裏我懶得安裝了,就直接介紹最後一條提示吧。

JETBRAINS QUEST: LAST PUZZLE
You have discovered our JetBrains Quest! If you don’t know what this is, you should start from the beginning.
This is it. The last puzzle. You are just one step away from glory!
Now you just need the Key to unlock the Quest page.
The Key is the first and last 4 digits of the 50 * 10^6 position of the Fibonacci sequence (F(50 Million)).
As you may know by now, not all that glitters is gold, and to solve this puzzle you should not go straight for the obvious answer. May you make a glorious choice.
Remember that you have until the 15th of March 12:00 CEST.

好吧,最後這個問題我是真的不會解了。他問的是斐波那契數列的第五千萬項的前四位數字和最後4位數字。這個數字超乎想象大的大,遠遠大於宇宙中所有原子的數目,數量級大約是10的一千萬次方。普通的暴力方法完全不管用。所以想偷懶的同學可以直接在Wolfram Alpha裏面計算fib(5e7)以及fib(5e7)mod10000,即可得到前後4位數字。

不過這個數字雖大,難道就真的無法計算了嗎?其實也不是不可以,因爲這個數字保存下來也就10兆左右的大小,還是在可計算範圍之內的,不過要使用非常高級的數學技巧。我搜了一下找到了這篇博客,裏面提到了一個論文裏面的分治算法。

使用它可以非常輕鬆的計算得到斐波那契的第五千萬項的內容,在我電腦上僅需35秒即可得到結果,簡直是太牛逼了。

// https://www.maplesoft.com/applications/download.aspx?SF=154362/fibonaccinumbers.pdf
// duplication formula
// f(2n)  = f(n)^2 + 2f(n-1)f(n)
// f(2n-1)= f(n)^2 + f(n-1)^2
fun fibonacci2(n: Int, cache: HashMap<Int, BigInteger>): BigInteger {
    if (n <= 1) {
        return BigInteger.valueOf(n.toLong())
    }

    return if (n % 2 == 0) {
        val b = cache.getOrPut(n / 2, { fibonacci2(n / 2, cache) })
        val a = cache.getOrPut(n / 2 - 1, { fibonacci2(n / 2 - 1, cache) })
        b * b + BigInteger.TWO * b * a
    } else {
        val b = cache.getOrPut((n + 1) / 2, { fibonacci2((n + 1) / 2, cache) })
        val a = cache.getOrPut((n - 1) / 2, { fibonacci2((n - 1) / 2, cache) })
        a * a + b * b
    }

}
fun main() {
    val profile = fun(task: () -> Unit) {
        val t1 = LocalDateTime.now()
        task()
        val t2 = LocalDateTime.now()
        println(Duration.between(t1, t2))
    }
    val c = HashMap<Int, BigInteger>()
    val n = 5e7.toInt()
    //profile { println(fibonacci1(n)) }
    profile { println(fibonacci2(n, c)) }
}

不管哪種方法,都可以得到最終結果,答案就是46023125,這就是最終的代碼。使用它即可獲取Jetbrains全家桶的八折優惠券。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章