質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

3回答

3742閲覧

*とスペースを用いたひし形を出力するプログラム

koto_koto

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2020/11/16 11:44

C言語

整数値を入力すると、*とスペースを用いたひし形を出力するプログラムを教えていただきたいです。
整数の値はひし形の中央の*の数です。

例:
整数を入力せよ:3
・・・*・・・
・・*〇*・・
・*〇*〇*・
・・*〇*・・
・・・*・・・

「・」「〇」はどちらも空白

よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

プログラムそのものではなく,方法のアイデアの話となりますが…

f(x,y) = cos(x) * cos(y)という式を考えました.プロットしてみると下図のような形です.
山と谷が交互に繰り返すような形をしています.
床(?)に表示されているのは等高線です.
この交互具合が,やりたいことに似ていると思います.

イメージ説明

こいつに適当に2次元正規分布g(x,y)を窓関数として用いてf(x,y)*g(x,y)としてやれば,
以下のように関数値が上下に振れる範囲を制限でき,雰囲気が本件の問題の内容にかなり近づくと思います.

イメージ説明

なので,この関数値に対して適切な閾値による二値化を行った結果を,スペースと'*'とで表示すれば良いのではないでしょうか.
(窓関数の広さとか,関数の位相あたりを入力された値に基づいて変えてやる必要はあると思います)


とりあえず愚直に実装するとこんなですかね.
コメントに書いたように,窓関数g(x,y)はifで置き換わっています.

(別の回答と同様に,数値入力は{面倒/本質ではない}のでdefineで済ませてあります)

C++

1#define N_THE_INPUT (3) 2 3const double PI = acos(-1.0); //π 4 5//f(x,y), 位相調整込み 6double F( double x, double y ) 7{ return ( N_THE_INPUT&0x01 ? cos(x)*cos(y) : -cos(x)*cos(y) ); } 8 9// 10int main(int argc, char *argv[]) 11{ 12 const double Thresh = 0.5; //関数f(x,y)に対する閾値 13 const int RANGE = ( N_THE_INPUT*2 - 1 ); 14 const int RANGE_CENTER = RANGE/2; 15 16 for( int row=0; row<RANGE; ++row ) 17 { 18 printf( "[ " ); 19 for( int col=0; col<RANGE; ++col ) 20 { 21 char out = ' '; 22 const int c = col - RANGE_CENTER; 23 const int r = row - RANGE_CENTER; 24 if( abs(c)+abs(r) < N_THE_INPUT ) //※市街地距離による矩形窓 25 { 26 if( F( PI*c, PI*r ) > Thresh ){ out = '*'; } 27 } 28 putchar( out ); 29 } 30 printf( " ]\n" ); 31 } 32 33 return 0; 34}

投稿2020/11/17 02:39

編集2020/11/18 01:37
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/11/17 02:50 編集

この問題では窓関数に市街地距離を用いると良いと思います. (示した図では何も考えずにユークリッド距離のガウス関数を使ってます) #まぁ,実際の実装においては「窓関数がどうの」の部分は 走査範囲の制限とかifあたりでの単純判断といった意味的に等価な物に置き換わると思うので 割とどうでもいいだろうな,とは思います.
Zuishin

2020/11/17 07:24

これは斬新。
fana

2020/11/17 08:44 編集

(蛇足な気がするけど,コードを追記.) (実際にコード化すると,割とまともな形(?)になるから困る.)
guest

0

いろいろな書き方があります。模範的な解答ではありません。

C

1#include <stdio.h> 2 3int main(void) 4{ 5 for (int s = 0, i = 1, j = 1, n, k = (scanf("%d", &n), n-1); i; ) 6 s==0 ? printf(" " ), !k-- && (k = i, s = 1) : 7 s==1 ? printf("* "), !--k && (k = n-i, s = 2) : 8 !k-- ? printf("\n"), i==n && (j = -1), s = 0, i += j, k = n-i : printf(" "); 9}

追記
fanaさんのコードを参考にしたら、こんなのが書けました。

C

1#include <stdio.h> // scanf, putchar 2#include <stdlib.h> // abs 3 4int main(void) 5{ 6 for (int n, i = (scanf("%d", &n), -n); ++i < n; putchar('\n')) 7 for (int j = -n; j <= n; j++) 8 putchar(" *"[(i+j ^ n) & 1 && abs(i)+abs(j) < n]); 9}

追記2
上記のコードは n が偶数の場合正しくなかったので修正しました。

追記3
fanaさんのライフゲーム風のコードをこんな風に書いてみました。

C

1#include <stdio.h> // scanf, printf 2#include <stdlib.h> // malloc. free 3#include <string.h> // memset 4 5#define transform(k, op) \ 6 for (int i = k; i < n; i++) { \ 7 printf("%.*s\n", w, a); \ 8 for (int j = 0; ++j < w-1; ) b[j] = " *"[a[j-1]=='*' op a[j+1]=='*']; \ 9 t = a, a = b, b = t; \ 10 } 11 12int main(void) { 13 int n, w = (scanf("%d", &n), n*2+1); 14 char *s = malloc(w*2), *a = memset(s, ' ', w*2), *b = (a[n] = '*', s+w), *t; 15 transform(1, |) transform(0, &) free(s); 16}

for文の (;;) を除いて、「;」が 1行に 1つという制約で短縮しています。

投稿2020/11/18 10:53

編集2020/11/20 04:58
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/11/20 04:38

市街地距離とnの最下位bitを比較することが真っ先に思いついた方法でしたが, なるほど,abs使わず単純に i+j^n で済むのですね.
kazuma-s

2020/11/20 04:52

(i+j ^ n) & 1 で市松模様、abs(i)+abs(j) < n で菱形の内側です。
fana

2020/11/20 05:08 編集

はい. 市松部分の記述だけを考えた場合に,私の頭だと ( (abs(i) + abs(j)) ^ n ) & 0x01 として,余計なabsが2つ付いてしまうところだなぁ,という感想です. 高評価の理由:個人的にこの行が好き. > putchar(" *"[(i+j ^ n) & 1 && abs(i)+abs(j) < n]);
guest

0

行の内容を簡単なルールに従って変換することで次の行の内容を作れるんじゃないか?(ライフゲームみたいに)
…とか思ったのですが,コードも無意味に長いしルールも1つに纏まらないしでイマイチ感.

提示コードでは,

整数値を入力

の部分はめんどくさい(し,話の本質でもない)のでdefineで済ませてます.

C++

1#define N_THE_INPUT (3) 2#define LEN (N_THE_INPUT*2+1) 3 4int Transform( const char *pSrc, char *pDst, int length, int Or ) 5{ 6 int i; 7 int ret = 0; 8 for( i=1; i<length-1; ++i ) 9 { 10 const unsigned char s1 = ( *(pSrc+i-1) == '*' ); 11 const unsigned char s2 = ( *(pSrc+i+1) == '*' ); 12 *(pDst+i) = ' '; 13 if( Or ? (s1 || s2) : (s1 && s2) ) 14 { 15 *(pDst+i) = '*'; 16 ++ret; 17 } 18 } 19 return ret; 20} 21 22int OrTransform( const char *pSrc, char *pDst, int length ) 23{ return Transform( pSrc, pDst, length, 1 ); } 24 25int AndTransform( const char *pSrc, char *pDst, int length ) 26{ return Transform( pSrc, pDst, length, 0 ); } 27 28void Init( char *pDst, int length ) 29{ 30 int i; 31 for( i=0; i<length; ++i ){ *(pDst+i)=' '; } 32} 33 34// 35int main(int argc, char *argv[]) 36{ 37 char Buff1[LEN+1] = { '\0' }; 38 char Buff2[LEN+1] = { '\0' }; 39 char *pS = Buff1; 40 char *pD = Buff2; 41 char *pT; 42 int n = 1; 43 44 Init( pS, LEN ); 45 Init( pD, LEN ); 46 47 { 48 *(pD+LEN/2) = '*'; 49 printf( "[%s]\n", pD ); 50 } 51 52 while( n < N_THE_INPUT ) 53 { 54 pT = pS; 55 pS = pD; 56 pD = pT; 57 n = OrTransform( pS, pD, LEN ); 58 printf( "[%s]\n", pD ); 59 } 60 61 while( n>1 ) 62 { 63 pT = pS; 64 pS = pD; 65 pD = pT; 66 n = AndTransform( pS, pD, LEN ); 67 printf( "[%s]\n", pD ); 68 } 69 70 return 0; 71}

投稿2020/11/17 05:08

fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問