どのくらい曇りですか?


22

チャレンジ

空の画像を指定すると、oktasで雲量を出力する必要があります。提供されるイメージはイメージファイル(タイプはユーザー次第)であり、出力はSTDOUTになります。

オクタス

気象学では、オクタは、気象観測所などの任意の場所での雲量を表すために使用される測定単位です。空の状態は、空の8分の何が雲で覆われているかによって推定され、0オクタ(完全に晴天)から8オクタ(完全に曇り)までの範囲です。

空は常に正午頃の写真になります(つまり、赤/夜空ではなく、青空)。

雲の色は、常に次のパターンに従う色になります。

#ABCDEF

どこAB >= C0CD >= C0そしてEF >= C0

または、RGB:

(A, B, C)

どこA >= 192B >= 192そしてC >= 192

oktasに関連するカバレッジの割合は次のとおりです。

0%    - 0 oktas
12.5% - 1 okta
25%   - 2 oktas
37.5% - 3 oktas
50%   - 4 oktas
62.5% - 5 oktas
75%   - 6 oktas
87.5% - 7 oktas
100%  - 8 oktas

割合は、雲である画像の割合です。

画像の雲の割合が12.5の倍数でない場合、最も近い値に丸める必要があります。

出力

出力は、単にokta番号である必要があります(ユニットを言う必要はありません)。

1 okta(18.030743615677714%クラウド)

0オクタ(0.0%クラウド)

3オクタ(42.66319444444445%クラウド)

1 okta(12.000401814778645%クラウド)

数値の計算に使用されるPythonコード

勝ち

バイト単位の最短コードが優先されます。


最後の3オクタではないですか?
TheLethalCoder

@TheLethalCoder Whoops、編集
ベータ崩壊

画像の寸法に最大値はありますか?
シャギー

2
整数のフロアリングを使用した回答は最初の3つのテストケースに合格するため、12.5に切り上げる必要がある4番目のテストケースを追加しました。
ジャスティンマリナー

1
C ++などの画像処理機能を持たない言語については、ライブラリを使用しても大丈夫ですか?その場合、バイトカウントについては、プログラムの実行に必要な記述されたコードまたはDLLファイルのサイズのみをカウントする必要がありますか?
HatsuPointerKun

回答:


10

パイソン2114の 110 98バイト

TheLethalCoderのおかげで-4バイト
Ruudのおかげで-12バイト

import PIL.Image as P
i=P.open(input()).getdata()
print round(8.*sum(min(x)>191for x in i)/len(i))

オンラインでお試しください!


191代わりに使用しますか?
TheLethalCoder

2
私は提案するつもりでしたx&y&z&192>191が、更新されたバージョンは同じくらい短いです。
アルノー

2
に変更するときに潜在的に1バイトに置き換えimport PIL.Image as Pfrom PIL.Image import*保存できますか?openは既に定義済みの関数であるため、それが問題を引き起こすかどうかはわかりませんが、モジュールをインストールする機能がないためテストできません。i=P.openi=open
アーノルドパーマー

1
ええ、それはうまくいくようです。1バイト節約します。
アルフィー

2
@Rodは、すべてのプラットフォームでコードを実行する必要はありません-言語はインタープリターによって定義されます。それがあなたのために動作する場合、それは有効です。
ティム

10

MATL18 17バイト

Yi191>3&A1eYm8*Yo

提供されている4つの画像を使用してサンプルを実行します(プレビューの品質については申し訳ありません。クリックすると最大解像度になります)。

ここに画像の説明を入力してください

または、最後の4文字を削除して、丸めなしで結果を表示します。

ここに画像の説明を入力してください

説明

Yi     % Implicitly input filename or URL. Read image. Gives an M×N×3 array
191>   % Does each entry exceed 191?
3&A    % True for 3rd-dim "lines" that only contain true. Gives an M×N matrix
1e     % Linearize (flatten) into a 1×L row vector, with L = M*N
Ym     % Mean of vector
8*     % Multiply by 8
Yo     % Round. Implicitly display

私はesolangsを使用して行うことができるのだろうか
ЕвгенийНовиков

6

Java(OpenJDK 8)、204バイト

i->{int x=0,y=0,t=0,w=i.getWidth(),h=i.getHeight();for(;x<w;)for(y=0;y<h;){java.awt.Color c=new java.awt.Color(i.getRGB(x++,y++));if(c.getRed()>191&&c.getBlue()>191&&c.getGreen()>191)t++;}return 8*t/w/h;}

オンラインでお試しください!TIOがデバッグタブにSTDERRを出力することを常に忘れています。エラーが発生した場合に赤でハイライト表示したい場合がありますか?


いくつかのこと:あなたはインクリメントしませんので、あなたのコードは、現在、無限ループで実行されますxyy=02回割り当てたので、最初の割り当てを削除できます。クラスColorは完全修飾(java.awt.Color)であるか、バイトカウントにインポートを含める必要があります。また、4番目のテストケースでコードが失敗します(1ではなく0を返します)。
ジャスティンマリナー

私はそれがしばらくしているが、知っていることができますforループの内側の金具を取り外し、および変更することによって、6バイトのゴルフ&&&,y=0まで,yオンラインそれを試してみてください。
ケビンクルーッセン

6

C#、150 146バイト

b=>{int t=0,c=0,w=0,h;for(;w<b.Width;++w)for(h=0;h<b.Height;++t){var p=b.GetPixel(w,h++);if(p.R>191&p.G>191&p.B>191)c++;}return(int)(c/(t+0d)*8);}

@Ian Hのおかげで4バイト節約

フル/フォーマット済みバージョン:

using System.Drawing;

namespace System
{
    class P
    {
        static void Main()
        {
            Func<Bitmap, int> f = b =>
            {
                int t = 0, c = 0, w = 0, h;
                for (; w < b.Width; ++w)
                    for (h = 0; h < b.Height; ++t)
                    {
                        var p = b.GetPixel(w, h++);

                        if (p.R > 191 & p.G > 191 & p.B > 191)
                            c++;
                    }

                return (int)(c / (t + 0d) * 8);
            };

            string[] testCases =
            {
                @"Appearance_of_sky_for_weather_forecast,_Dhaka,_Bangladesh.JPG",
                @"spanish-sky.jpeg",
                @"why-is-sky-blue-1.jpg",
            };

            foreach (string testCase in testCases)
            {
                using (Bitmap bitmap = new Bitmap(testCase))
                {
                    Console.WriteLine(f(bitmap));
                }
            }

            Console.ReadLine();
        }
    }
}

for(h=0 h<b.Height;++t)私はあなたがそこにセミコロンを逃したと思う
KritixiのLithos

2
最後に/0.125with *8を置き換えて、数バイトを節約できます。
イアンH.

@Cowsquackスペースの代わりにセミコロンを削除しました!今修正..
TheLethalCoder

3

C#、313バイト

namespace System.Drawing.Imaging{b=>{unsafe{int t=0,c=0,y=0,x,w=b.Width,h=b.Height;var d=b.LockBits(new Rectangle(0,0,w,h),(ImageLockMode)1,(PixelFormat)137224);for(;y<h;++y){var r=(byte*)d.Scan0+y*d.Stride;for(x=0;x<w*3;++t)if(r[x++]>191&r[x++]>191&r[x++]>191)c++;}b.UnlockBits(d);return(int)(c/(t+0d)/0.125);}}}

明らかに私の他の答えよりも長いが、このいずれかを使用LockBitsし、unsafe、直接メモリ内の画像にアクセスするためのコード; そのため、非常に高速です。への呼び出しを削除することもできUnlockBitsますが、そこではより正確です。

フル/フォーマット済みバージョン:

namespace System.Drawing.Imaging
{
    class P
    {
        static void Main()
        {
            Func<Bitmap, int> f = b =>
            {
                unsafe
                {
                    int t = 0, c = 0, y = 0, x, w = b.Width, h = b.Height;

                    var d = b.LockBits(new Rectangle(0, 0, w, h), (ImageLockMode)1, (PixelFormat)137224);
                    for (; y < h; ++y)
                    {
                        var r = (byte*)d.Scan0 + y * d.Stride;

                        for (x = 0; x < w * 3; ++t)
                            if (r[x++] > 191 & r[x++] > 191 & r[x++] > 191)
                                c++;
                    }
                    b.UnlockBits(d);

                    return (int)(c / (t + 0d) / 0.125);
                }
            };

            string[] testCases =
            {
                @"Appearance_of_sky_for_weather_forecast,_Dhaka,_Bangladesh.JPG",
                @"spanish-sky.jpeg",
                @"why-is-sky-blue-1.jpg",
            };

            foreach (string testCase in testCases)
            {
                using (Bitmap bitmap = new Bitmap(testCase))
                {
                    Console.WriteLine(f(bitmap));
                }
            }

            Console.ReadLine();
        }
    }
}

3

PowerShell、200バイト

$a=New-Object System.Drawing.Bitmap $args[0]
0..($a.Height-1)|%{$h=$_;0..($a.Width-1)|%{$i+=(("$($a.GetPixel($_,$h)|select R,G,B)"|iex)['R','G','B']-ge192).count-eq3}}
[int]($i/($a.Height*$a.Width)*8)

入力$args[0]をフルイメージファイルパスとして取得し、New Bitmapオブジェクトを構築します$a。これは単なる内部オブジェクト名です。JPG、PNGなどをサポートしています。

次に、をダブルループし、.height次にを.widthタッチして、それぞれに触れますpixel。私たちは、引き抜きR,G,B値をして、あるものを選択-greaterthanor eにQUALを192し、必ずそれが作るcountである3(すなわち、それらのすべてが白っぽいです)。そのブール結果はアキュムレーターに追加されます$i

次に、パーセンテージを取得するために分割し8、oktasの数を取得するために乗算してから[int]、整数出力のみを取得します。(これは銀行家の丸めを実行することに注意してください-それが許可されていない場合、丸め方法を変更するためにさらに数バイトになるでしょう。)



2

JavaScript、83 77バイト

ETHproductionsによる -6バイト

f=i=>(z=a=b=0,i.map(e=>{z=e<192||z;(++b%4)||((z||(a+=64))&&(z=0))}),a/b+1>>1)

入力

写真1

写真#2

写真#3

写真#4

デモ


1
とてもいい解決策。ES6矢印関数の便利なトリックは、すべてを括弧で囲み、またはのa=>(b,c,d)代わりにコンマ()で区切ることです。何らかのループがある場合を除き、これは機能します。その場合は、おそらくメソッドを使用するのが最善でしょう。a=>{b;c;return d}a=>eval("b;c;d")eval
-ETHproductions

2

C(POSIX)、103バイト

入力を標準入力のBMPファイルとして想定します。

b,c,i,m=0xc0c0c0;main(){lseek(0,54,0);for(;read(0,&b,3);c+=(b&m)==m,i++);printf("%d",(i+16*c)/(2*i));}

2

x86マシンコード、34バイト

51
31 D2
AD
F7 D0
25 C0 C0 C0 00
75 01
42
E2 F3
C1 E2 03
DB 04 24
52
DB 04 24
DE F1
DB 1C 24
58
5A
C3

これらのコードバイトは、ビットマップ入力を受け取り、oktasを示す整数値を返す関数を定義します。Cのようにと、配列(ビットマップなど)は、最初の要素へのポインターとサイズ/長さとして表されます。したがって、この関数は2つのパラメーターを取ります。ビットマップ内のピクセルの総数(行×列)とビットマップ自体へのポインターです。

このコードは、カスタムレジスタベースの呼び出し規則を使用します。この規則では、ビットマップポインターがESIレジスターに渡され、ビットマップサイズがECXレジスターに渡されます。結果(oktas)は、通常、で返されEAXます。

すでに上で述べたように、入力はビットマップとして取得されます。具体的には、リトルエンディアン形式で32 bpp形式が使用されますが、アルファチャネル(最上位バイト)は無視されます。これにより、多くのことが単純化され、各ピクセルを単純に反復処理し、32ビットRGBカラー値を確認できるようになります。巧妙な最適化もここで使用されます。各色成分を分離して192以上かどうかをチェックする代わりに、32ビット値全体を0xC0C0C0でマスクし、結果が0xC0C0C0以上かどうかをテストします。これは、すべての「雲」色に対してtrue、すべての「空」(雲以外)色に対してfalseと評価されます。まあ、私ははそれが賢いと思った!:-)それは確かに大量のバイトを節約します。

したがって、このコードをテストするには、入力画像を32-bppビットマップに変換する必要があります。これにはWindowsペイントを使用できません。これは、ピクセルあたり最大24ビットをサポートしているためです。ただし、Adobe Photoshopなど、それを実行できるソフトウェアソリューションは他にも多数あります。この無料ツールを使用しましたWindowsでPNGを32-bpp BMPに変換するしました。つまり、JPEGからPNGに変換するだけで済みます(ペイントで実行できます)。

私が主張する他の仮定は非常に合理的です:

  • ビットマップのサイズは0より大きいと想定されます(つまり、と想定されます、少なくとも1つのピクセルが含まれていると想定されます)。空が空のとき、気象よりも大きな問題があるため、これは合理的です。
  • 命令DFを使用してビットマップを正しく反復処理するために、方向フラグ()はクリアされていると想定されますLODSD。これは、ほとんどのx86呼び出し規約で行われた仮定と同じであるため、公平に思えます。気に入らなければ、1バイトをカウントに追加しますCLD命令のください。
  • x87 FPUの丸めモードは、最も近い偶数に丸められるように設定されていると想定されています。これにより、テストケース#4で検証されているように、oktasの数を一時的な浮動小数点から最終的な整数結果に変換するときに正しい動作が得られます。これは、FPUのデフォルトの状態であるので、この仮定は妥当であるの願いが丸めを変える非効率的なコードを生成するために、標準に準拠することをコンパイラに強制的に、さえ切り捨てがデフォルトの動作を丸めているCコード(に維持する必要がありますモード、変換を行ってから、丸めモードを元に戻します)。

非ゴルフアセンブリニーモニック:

; int ComputeOktas(void*    bmpBits  /* ESI */,
;                  uint32_t bmpSize  /* ECX */);
   push  ecx                  ; save size on stack
   xor   edx, edx             ; EDX = 0 (cloudy pixel counter)

CheckPixels:
   lodsd                      ; EAX = DS:[ESI]; ESI += 4
   not   eax
   and   eax, 0x00C0C0C0
   jnz   NotCloudy
   inc   edx
NotCloudy:
   loop  CheckPixels          ; ECX -= 1; loop if ECX > 0

   shl    edx, 3              ; counter *= 8
   fild   DWORD PTR [esp]     ; load original size from stack
   push   edx
   fild   DWORD PTR [esp]     ; load counter from stack
   fdivrp st(1), st(0)        ; ST(0) = counter*8 / size
   fistp  DWORD PTR [esp]     ; convert to integer, rounding to nearest even
   pop    eax                 ; load result
   pop    edx
   ret

確かにあなたはこれまでずっとそれを下しておらず、まだコードがどのように機能するのか疑問に思っていますか?:-)
まあ、それは非常に簡単です。一度に32ビット値ずつビットマップを反復処理し、そのピクセルRGB値が「曇っている」か「曇っていない」かを確認します。曇りの場合は、事前にゼロ化されたカウンターをインクリメントします。最後に、曇りピクセル合計ピクセル  ×8
(これは、曇りピクセル合計ピクセル  ÷0.125 と同等)を計算します。

入力画像が必要なため、このためのTIOリンクを含めることはできません。ただし、Windowsでこれをテストするために使用したハーネスを提供できます。

#include <stdio.h>
#include <assert.h>
#include <Windows.h>

int main()
{
   // Load bitmap as a DIB section under Windows, ensuring device-neutrality
   // and providing us direct access to its bits.
   HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,
                                        TEXT("C:\\...\\test1.bmp"),
                                        IMAGE_BITMAP,
                                        0, 0,
                                        LR_LOADFROMFILE  | LR_CREATEDIBSECTION);
   assert(hBitmap != NULL);

   // Get the bitmap's bits and attributes.
   DIBSECTION dib;
   GetObject(hBitmap, sizeof(dib), &dib);
   assert(dib.dsBm.bmBitsPixel == 32);
   uint32_t cx = dib.dsBm.bmWidth;
   uint32_t cy = abs(dib.dsBm.bmHeight);
   uint32_t sz = cx * cy;
   assert(sz > 0);

   int oktas = ComputeOktas(sz, dib.dsBm.bmBits);

   printf("%d\n", oktas);

   return 0;
}

ただし、これには注意してください!上記で定義されているように、ComputeOktasCコンパイラが尊重しないカスタム呼び出し規約を使用します。アセンブリ言語プロシージャの先頭にコードを追加して、スタックから期待されるレジスタに値をロードする必要があります。

mov  ecx, DWORD PTR [bmpSize]
mov  esi, DWORD PTR [bmpBits]

1

JavaScript(ES6)、218バイト

(a,c=document.createElement`canvas`,w=c.width=a.width,h=c.height=a.height,x=c.getContext`2d`)=>x.drawImage(a,0,0)||x.getImageData(0,0,w,h).data.reduce((o,_,i,d)=>o+(i%4|d[i++]<192|d[i++]<192|d[i]<192?0:1),0)/w/h*8+.5|0

かかるImageから作成することができ、入力としてオブジェクト、<image>要素。

CodePenでテストしてみてください!

代替案

入力がRGBA値のフラット配列として取得できる場合、寸法は82バイト

(d,w,h)=>d.reduce((o,_,i)=>o+(i%4|d[i++]<192|d[i++]<192|d[i]<192?0:1),0)/w/h*8+.5|0

この入力形式は、メタに関するこの回答が示唆するものと非常に似ています。


1

Mathematica 89バイト

以下は画像を二値化し、雲の割合、つまり白いピクセルを決定します。次に、結果に.125が適合する回数を決定します。その値の下限を返します。

o@i_:=⌊8Tr@Flatten[ImageData@MorphologicalBinarize[i,.932],1]/Times@@ImageDimensions@i⌋
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.